Repository navigation
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
Description
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
- Sign in to
https://flow.google.com/, leave one tab open, extension connected. 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}'- 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
buiminhhieu-svg commentedon Sep 23, 2026
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:UNUSUAL_ACTIVITYSo 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
mainatce37f4b(PR #39, the batchexecute migration, 2026-09-07)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) andogiZ0b(image) both fail, while polling, project media and url refresh keep working normally. One of our jobs died at theGENERATE_IMAGEstep 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 noUNUSUAL_ACTIVITYat 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.executefrom the MAIN world with a matching site key and action.Happy to run any probe that would help narrow it further.
gwozd3k commentedon Sep 23, 2026
I pointed astra at this problem, and it did not come up with any solution...
Bl0ck154 commentedon Sep 23, 2026
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:eb1hJf->PUBLIC_ERROR_UNUSUAL_ACTIVITYeb1hJf-> HTTP 200MEDIA_GENERATION_STATUS_SUCCESSFULogiZ0bimage generation through the same production Playwright path -> HTTP 200, generated image returnedSo 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.Bl0ck154 commentedon Sep 24, 2026
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:
document.readyState=complete), visible,grecaptcha.enterprisepresent, andnavigator.webdriver=false;ogiZ0bafter the project tab has remained open/warm also returns the same rejection;flow2apiusers 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.
fix(extension): mint reCAPTCHA via hidden widget + preload grecaptcha…
crisng95 commentedon Sep 27, 2026
fixed, close
xiaoyi9096 commentedon Oct 15, 2026
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
ogiZ0bsucceeded 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 receivedPUBLIC_ERROR_UNUSUAL_ACTIVITYon 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:
YhhmEfexclusively, or is there a verified current case where legacybatchAsyncGenerateVideoTextremains appropriate? The source builders agree onabra_t2v_8s, but that alone does not establish transport equivalence.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?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.