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

  1. Retry the request — transient CDN/format glitches often resolve and the token fetch is retried.
  2. Update g4f to pick up new extraction regexes after Alibaba changes.
  3. Bypass JS-rewriting proxies when fetching alibaba domains.
  4. 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

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


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/b2a2c5897f26db68. Report an issue: GitHub.