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.
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
(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
batchexecutecall.Environment
main@ d7977fd)boq_labs-ai-sandbox-frontend_20260922.00_p0What works and what does not
ogiZ0bgenerate imageeb1hJfgenerate videoSPrCad2K image exportjwpdufpoll operationZzl0zeproject mediaas29smedia urls (/api/flow/refresh-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
MAX_CONCURRENT_REQUESTS=2,API_COOLDOWN=30google.com+labs.googlecookies, signed back inWIZ_global_data.cfb2h= new build id)grecaptcha.enterprise.executein the page: the UI mints with actionIMAGE_GENERATIONand site key6LdsFiUsAAAAAIjVDZcuLhaHiDn5nnHVXVRQGeMV— identical toflow_batch.CAPTCHA_IMAGEandinjected.jsf.reqperdocs/CAPTURE.mdand diffed againstflow_batch.image_request()— same slots, sameGEM_PIX_2, same aspect code, same context envelope, captcha token of comparable lengthContent-Type,Referer,Sec-Ch-Ua-*,User-Agent,X-Same-Domain: 1— the extension already sendscontent-type+x-same-domain, the rest are added by Chromebackground.jssubstitutes one token into both captcha slots (freq.split(CAPTCHA_SLOT).join(token)). Patched it to mint one fresh token per slot and retriedReproduce
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}'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'sMAIN 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 andconcat all run normally. Scenes without a clip can be filled with a Ken Burns
move built from the scene image locally with ffmpeg.