xtekky/gpt4free · error · RuntimeError
Failed to extract bx-umidtoken.
Error message
Failed to extract bx-umidtoken.
What it means
Raised by Qwen._get_req_headers when the fetched wu.json from sg-wum.alibaba.com does not contain a umid token matching either regex (umx.wu('...') or __fycb('...')). The bx-umidtoken is Alibaba's device-fingerprint token required in request headers; a non-matching response means Alibaba changed the script format or served an error/obfuscated payload.
Source
Thrown at g4f/Provider/Qwen.py:472
# Fix 'FAIL_SYS_USER_VALIDATE'
"X-Accel-Buffering": "no",
}
if token:
headers["Authorization"] = f"Bearer {token}"
return headers
@classmethod
async def _get_req_headers(cls, session, proxy=None):
if not cls._midtoken:
debug.log("[Qwen] INFO: No active midtoken. Fetching a new one...")
async with session.get(
"https://sg-wum.alibaba.com/w/wu.json", proxy=proxy
) as r:
r.raise_for_status()
text = await r.text()
match = re.search(r"(?:umx\.wu|__fycb)\('([^']+)'\)", text)
if not match:
raise RuntimeError("Failed to extract bx-umidtoken.")
cls._midtoken = match.group(1)
cls._midtoken_uses = 1
debug.log(
f"[Qwen] INFO: New midtoken obtained. Use count: {cls._midtoken_uses}. Midtoken: {cls._midtoken}"
)
else:
cls._midtoken_uses += 1
debug.log(f"[Qwen] INFO: Reusing midtoken. Use count: {cls._midtoken_uses}")
req_headers = session.headers.copy()
req_headers["bx-umidtoken"] = cls._midtoken
req_headers["bx-v"] = "2.5.36"
# fix error [g4f.errors.CloudflareError:aliyun_waf_aa]
req_headers["x-request-id"] = str(uuid.uuid4())
return req_headers
@classmethod
async def get_quota(cls, api_key: Optional[str] = None, **kwargs) -> dict:
View on GitHub (pinned to 973504e177)
Solutions
- Retry the request — transient CDN/format glitches often resolve and the token fetch is retried.
- Update g4f to pick up new extraction regexes after Alibaba changes.
- Bypass JS-rewriting proxies when fetching alibaba domains.
- If persistent, inspect wu.json manually and patch the regex in _get_req_headers.
Example fix
# before
r = await Qwen.create_async_generator(model, msgs)
# after
for attempt in range(2):
try:
r = await Qwen.create_async_generator(model, msgs)
break
except RuntimeError as e:
if 'bx-umidtoken' not in str(e) or attempt == 1:
raise
await asyncio.sleep(5) Defensive patterns
Strategy: retry
Try / catch
try:
r = await Qwen.create_async_generator(model, msgs)
except RuntimeError as e:
if 'bx-umidtoken' in str(e):
await asyncio.sleep(5)
r = await Qwen.create_async_generator(model, msgs) # refetches wu.json
else:
raise Prevention
- Update g4f promptly — umid script format rotates
- Avoid proxies that rewrite JS bodies
- Retry once on token extraction failure before escalating
- File an upstream issue if it persists; regex needs updating
When it happens
Trigger: First request after startup (or after midtoken invalidation) when the wu.js/wu.json device script no longer contains the expected call pattern: format change, geo-varied payload, or proxy mangling the JS response.
Common situations: g4f version older than an Alibaba script rotation; corporate proxies rewriting JS; region-specific wu.json variants; transient CDN errors returning error bodies with status 200.
Related errors
- {captcha}
- {message or html}
- No response
- Failed to extract nonce from PhindAi response
- Failed to decode JSON from PhindAi response: {text}
AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14).
Data as JSON: /api/errors/b2a2c5897f26db68.
Report an issue: GitHub.