Skip to content

Every captcha-gated RPC returns PUBLIC_ERROR_UNUSUAL_ACTIVITY since the Flow frontend build of 2026-09-22, while the UI itself still works #58

Closed

Description

@123456wwwaaa-byte

Every captcha-gated RPC returns PUBLIC_ERROR_UNUSUAL_ACTIVITY since the Flow frontend build of 2026-09-22, while the UI itself still works

Summary

Since Google deployed the Flow frontend build boq_labs-ai-sandbox-frontend_20260922.00_p0,
every RPC that carries a reCAPTCHA token fails from Flow Kit with

RpcError: ogiZ0b failed: [7, None, [['type.googleapis.com/google.rpc.ErrorInfo', ['PUBLIC_ERROR_UNUSUAL_ACTIVITY']]]]

(grpc code 7 = PERMISSION_DENIED). The same account, in the same browser, in the
same tab, generates fine when the button is clicked in the Flow UI — including
when the click is driven by automation. So this is not an account, IP or
rate-limit block: it is specific to the extension's own batchexecute call.

Environment

Flow Kit 1.3.1 (main @ d7977fd)
Extension 0.3.2
Flow frontend boq_labs-ai-sandbox-frontend_20260922.00_p0
OS / browser Windows 11, Chrome 153
Transport batchexecute (no bearer, as expected)

What works and what does not

RPC Captcha Result
ogiZ0b generate image yes UNUSUAL_ACTIVITY
eb1hJf generate video yes UNUSUAL_ACTIVITY
SPrCad 2K image export yes UNUSUAL_ACTIVITY
jwpduf poll operation no OK
Zzl0ze project media no OK
as29s media urls (/api/flow/refresh-urls) no OK, refreshed 108 urls

The break was abrupt: on 2026-09-22 the same project generated 70 scene images
and 24 videos without a single UNUSUAL_ACTIVITY, then every generation failed
from roughly 22:50 local time onward.

What I ruled out

Hypothesis How it was tested Result
Burst / rate limit 1 single request after hours idle, MAX_CONCURRENT_REQUESTS=2, API_COOLDOWN=30 still fails
Account or IP blocked generated in the Flow UI on the same account UI works
Stale cookies cleared google.com + labs.google cookies, signed back in still fails
Stale tab on the old build closed every Flow tab, opened one fresh tab (WIZ_global_data.cfb2h = new build id) still fails
No user interaction in the minting tab scrolled/moved the mouse in the only open Flow tab, fired one request immediately still fails
Wrong captcha action / site key hooked grecaptcha.enterprise.execute in the page: the UI mints with action IMAGE_GENERATION and site key 6LdsFiUsAAAAAIjVDZcuLhaHiDn5nnHVXVRQGeMV — identical to flow_batch.CAPTCHA_IMAGE and injected.js identical
Payload shape drift recorded the UI's f.req per docs/CAPTURE.md and diffed against flow_batch.image_request() — same slots, same GEM_PIX_2, same aspect code, same context envelope, captcha token of comparable length identical
Missing header compared the UI's request headers: only Content-Type, Referer, Sec-Ch-Ua-*, User-Agent, X-Same-Domain: 1 — the extension already sends content-type + x-same-domain, the rest are added by Chrome nothing missing
Single-use token replayed background.js substitutes one token into both captcha slots (freq.split(CAPTCHA_SLOT).join(token)). Patched it to mint one fresh token per slot and retried still fails

Reproduce

  1. Sign in to https://flow.google.com/, leave one tab open, extension connected.
  2. curl -s -X POST http://127.0.0.1:8100/api/flow/generate-image -H "Content-Type: application/json" -d '{"prompt":"a calm river valley at dawn","project_id":"<uuid>","aspect_ratio":"IMAGE_ASPECT_RATIO_LANDSCAPE","count":1}'
  3. Click Generate on the same prompt in the Flow UI — it succeeds.

Question for maintainers

Given that the payload, the captcha action, the site key and the request headers
all match the UI byte for byte, what else distinguishes a token minted by
injected.js (grecaptcha.enterprise.execute(SITE_KEY, {action}) in the page's
MAIN world) from one minted by the app itself? Does the 2026-09-22 build bind the
assessment to something beyond the site key and action — a widget/client id, a
challenge context, or a second token — that the extension would now have to
reproduce?

Possibly related, both unanswered: #11, #12 (repeated API_403 on GENERATE_VIDEO
with MAX_CONCURRENT_REQUESTS=1).

Workaround in the meantime

Anything that does not need a captcha still works, so a project whose images are
already generated can still be finished: refresh-urls, narration, trimming and
concat all run normally. Scenes without a clip can be filled with a Ken Burns
move built from the scene image locally with ffmpeg.

Activity

  1. buiminhhieu-svg commented on Sep 23, 2026

    @buiminhhieu-svg

    Independent reproduction here, on a different account, different network, different OS and a different timezone. Everything below is measured from our own logs, not inferred.

    The transition window, in UTC

    Our agent ran all day on 2026-09-22 without a single UNUSUAL_ACTIVITY, then flipped inside one hour:

    local (UTC+7) UTC
    last successful video generation 2026-09-22 23:45:51 2026-09-22 16:45:51
    first UNUSUAL_ACTIVITY 2026-09-23 00:52:19 2026-09-22 17:52:19

    So the switch happened between 16:45 and 17:52 UTC on 2026-09-22. Nothing on our side changed in that window: no update, no restart, no re-login, no network change. 63 failures since, and not one success.

    Environment

    Flow Kit local fork branched off main at ce37f4b (PR #39, the batchexecute migration, 2026-09-07)
    Extension 0.3.2
    OS / browser Windows 10 Pro 19045, Chrome 153.0.8010.36
    Network residential IP, Vietnam, no VPN or proxy
    Account a different Google account from the reporter's

    Different major OS version and a fork that predates d7977fd, so this is not build-specific or account-specific on our end.

    What our numbers add

    Rate limiting is ruled out from a second direction. Our worker installs a 60 minute hard pause after each block, so the account sits completely idle, zero requests, then submits exactly one. That first submit after an hour of silence still failed in 0.7 seconds (eb1hJf, 2026-09-23 10:30:38 to 10:30:39 local). A cooldown that long with a single request is the opposite of a burst.

    Same RPC split as yours. eb1hJf (video) and ogiZ0b (image) both fail, while polling, project media and url refresh keep working normally. One of our jobs died at the GENERATE_IMAGE step before it ever reached video, so it is not video-specific.

    Not per-profile WAF heat. The same account, same profile, same machine had generated fine for hours right up to 16:45 UTC. Clearing cookies and signing back in did not help here either, matching your table.

    One ecosystem signal that may narrow it down

    Two other projects, checked today:

    • TheSmallHanCat/flow2api, which also builds the request itself and mints its own token, reports the same break starting 2026-09-22 (issue 177, and issue 162 opened today asking what a working captcha path even is now).
    • ffroliva/gflow-cli, which does not mint a token at all and instead drives the real Flow UI so the page's own JavaScript issues the request, ran its nightly live canary at 2026-09-23 02:00 UTC with no UNUSUAL_ACTIVITY at all. Its failures that night are unrelated (credits endpoint, agent mode).

    That is consistent with your own observation that clicking in the UI still works, including when the click is automation driven. Inference, not measurement, but it is the shape of the thing: whatever the assessment now binds to appears to be supplied by the page's own submit path, and not reproducible by calling grecaptcha.enterprise.execute from the MAIN world with a matching site key and action.

    Happy to run any probe that would help narrow it further.

  2. gwozd3k commented on Sep 23, 2026

    @gwozd3k

    I pointed astra at this problem, and it did not come up with any solution...

  3. Bl0ck154 commented on Sep 23, 2026

    @Bl0ck154
    Contributor

    I have a working reproduction/fix path now.

    Measured on the same signed-in Chrome profile/account/project where the existing captcha-gated transport consistently returned PUBLIC_ERROR_UNUSUAL_ACTIVITY:

    • raw/direct captcha-gated path: eb1hJf -> PUBLIC_ERROR_UNUSUAL_ACTIVITY
    • Playwright attached to the same already-authenticated persistent Chrome via CDP, driving the real Flow composer and only observing Flow's own request/response: eb1hJf -> HTTP 200
    • production API after switching generation submits to that Playwright UI path: fresh multipart upload -> Omni first-frame 10s/720p -> HTTP 200 -> MEDIA_GENERATION_STATUS_SUCCESSFUL
    • ogiZ0b image generation through the same production Playwright path -> HTTP 200, generated image returned

    So the important distinction is not payload shape. Our drift check showed the expected builder payload and the actual UI payload structurally matched. The reliable fix is to stop minting/submitting captcha-gated generation RPCs ourselves and let Flow's own SPA own the full submit path; automation should only drive the visible UI and capture the resulting response.

    Non-captcha RPCs (Zzl0ze, polling, media URLs, project lifecycle) can remain on batchexecute.

    Working fork commit: Bl0ck154@e54393f

    That commit uses playwright.chromium.connect_over_cdp() against the existing authenticated Chrome; it does not launch a second browser/profile. I also confirmed a fresh uploaded source works end-to-end in production after this switch.

  4. Bl0ck154 commented on Sep 24, 2026

    @Bl0ck154
    Contributor

    Follow-up / correction to my previous comment: the Playwright UI path is not a complete fix.

    It did produce real successful image and 10s/720p video generations yesterday on the same server/profile, but after a full Chrome + agent restart today the captcha-gated submits are being rejected again with PUBLIC_ERROR_UNUSUAL_ACTIVITY.

    Additional measurements today:

    • persistent login/auth/session are valid after restart;
    • Flow page is fully loaded (document.readyState=complete), visible, grecaptcha.enterprise present, and navigator.webdriver=false;
    • waiting for the page to warm up does not help;
    • retrying a single small ogiZ0b after the project tab has remained open/warm also returns the same rejection;
    • expected vs actual Flow UI request fingerprint still matches (no payload drift);
    • upstream flow2api users are independently reporting that headed/built-in browser captcha paths are failing after the update too.

    So I no longer consider connect_over_cdp() + normal Playwright clicks a stable workaround. The evidence now fits a server-side WAF/reCAPTCHA risk score on the browser profile/session (or another ephemeral browser assessment) much better than a wire-format problem.

    I also found a local FlowKit flaw that can make this worse: the unusual-activity breaker was only 120 seconds and reset on agent restart, while Google-side risk obviously does not reset with our process. I changed our fork to a 30-minute persistent breaker that survives restarts and never hot-retries an unusual-activity rejection:
    Bl0ck154@7be6093

    I am stopping automatic generation probes on this profile for now rather than increasing its WAF heat. If anyone has a current post-2026-09-24 successful reproduction after a cold browser start, especially using the stock UI without captcha injection, that comparison would be useful.

  5. crisng95 commented on Sep 27, 2026

    @crisng95
    Owner

    fixed, close

  6. xiaoyi9096 commented on Oct 15, 2026

    @xiaoyi9096

    Following up on the closure of this issue and #64: is there a currently verified explanation for the submit-context difference, especially after a cold start?

    We are comparing authorized, anonymized single-account tests. Earlier cookie-auth image generation over ogiZ0b succeeded without a running browser; a later account-independent CAPTCHA context plus Omni text-video submission did not. A fresh third-party token and our separate JS-runtime token both received PUBLIC_ERROR_UNUSUAL_ACTIVITY on the legacy REST video path. These are different experiments, so we are not attributing the failure to a measured score or claiming a stable browser-free solution.

    Could maintainers clarify:

    1. For migrated accounts, should current Omni text-to-video use YhhmEf exclusively, or is there a verified current case where legacy batchAsyncGenerateVideoText remains appropriate? The source builders agree on abra_t2v_8s, but that alone does not establish transport equivalence.
    2. Beyond matching site key, VIDEO_GENERATION, fresh single-use token and returned User-Agent, is there a documented app/widget initialization or submit-context requirement that explains the UI versus standalone-execute() difference in this issue?
    3. Has anyone reproduced a recent successful cold start with a fully account-independent CAPTCHA session, or does the reported fix still rely on the authenticated Flow page context?

    A dated successful reproduction or relevant commit would help more than an assumed minScore. No cookies, tokens, account/project identifiers or raw HAR files are included here. We have stopped generation probes while investigating.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions