{"record":{"id":"7464fb55b9d21ba7","repo":"DIYgod/RSSHub","slug":"zhihu-wasm-vm-did-not-produce-a-zse-ck","errorCode":null,"errorMessage":"zhihu: WASM VM did not produce a __zse_ck","messagePattern":"zhihu: WASM VM did not produce a __zse_ck","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/routes/zhihu/utils.ts","lineNumber":182,"sourceCode":"                Reflect.apply(cookieDescriptor.set!, window.document, [value]);\n                const token = value.match(/__zse_ck=([^;]+)/)?.[1];\n                if (token?.includes('-')) {\n                    resolve(token);\n                }\n            },\n        });\n    });\n\n    let zseCk: string | undefined;\n    try {\n        // Zhihu's challenge is intentionally delivered as executable JavaScript.\n        new Script(vmScript).runInContext(dom.getInternalVMContext());\n        zseCk = (await Promise.race([tokenPromise, wait(3000)])) as string | undefined;\n    } finally {\n        window.close();\n    }\n    if (!zseCk) {\n        throw new Error('zhihu: WASM VM did not produce a __zse_ck');\n    }\n    return { dc0, zseCk, ua };\n};\n\nconst getGeneratedZseCredentials = (url: string, apiPath: string, configuredDc0: string) => {\n    const cacheKey = `zhihu:zse-ck:v4:${configuredDc0 ? md5(configuredDc0) : 'guest'}`;\n    const pending = pendingZseCredentials.get(cacheKey);\n    if (pending) {\n        return pending;\n    }\n\n    const created = (async () => {\n        try {\n            return await cache.tryGet(cacheKey, () => generateZseCk(url, apiPath, configuredDc0), config.cache.contentExpire, false);\n        } finally {\n            pendingZseCredentials.delete(cacheKey);\n        }\n    })();","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/zhihu/utils.ts#L164-L200","documentation":"Thrown when the challenge script, executed inside the JSDOM VM context, fails to set a valid `__zse_ck` cookie token within the 3-second race timeout. The generator runs Zhihu's obfuscated WASM-backed script and watches the intercepted `document.cookie` writes for a token containing `-`; if none arrives before `wait(3000)` resolves, `zseCk` stays undefined and this error fires.","triggerScenarios":"Zhihu's challenge script changed its algorithm/output so the cookie it sets no longer matches the `__zse_ck=([^;]+)` pattern or no longer contains `-`; the WASM module failed to load/run in the JSDOM sandbox; or computation simply exceeded the 3 s budget under load.","commonSituations":"Zhihu updates the `__zse_ck` generation logic (new version, different token format); the VM lacks a needed global (`TextEncoder`/`atob`/`__g`) so the script errors silently; a CPU-constrained host makes 3 s too tight; a JSDOM/Node version incompatibility breaks `runInContext`.","solutions":["Supply `config.zhihu.cookies` with a freshly captured `d_c0` (and `__zse_ck` if your flow caches it) to reduce reliance on the in-VM generator.","Inspect whether the token format changed — if Zhihu stopped embedding `-`, relax the `token?.includes('-')` guard and the regex accordingly after verifying.","Increase the `wait(3000)` budget only if profiling shows the script legitimately needs more time on your hardware; a structural failure will not be fixed by a longer timeout.","Confirm required globals (`TextEncoder`, `TextDecoder`, `atob`, `btoa`, `__g`) are injected before `runInContext`."],"exampleFix":"// before\nzseCk = (await Promise.race([tokenPromise, wait(3000)])) as string | undefined;\n// after — longer budget plus a debug hook to see what cookie was set\nzseCk = (await Promise.race([tokenPromise, wait(8000)])) as string | undefined;\nif (!zseCk) {\n    console.debug('zhihu zse-ck challenge produced cookie:', lastSeenCookie);\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Retry the in-VM challenge with backoff; surface what cookie was seen on failure\nlet zseCk;\nfor (let i = 0; i < 2; i++) {\n    try {\n        zseCk = await runChallengeOnce(vmScript, dom);\n        if (zseCk) break;\n    } catch (e) { /* last attempt rethrows below */ }\n}\nif (!zseCk) throw new Error('zhihu: WASM VM did not produce a __zse_ck');","preventionTips":["Provide ZHIHU_COOKIES so the WASM challenge path is avoided entirely.","Verify required globals (TextEncoder, TextDecoder, atob, btoa, __g) are injected before runInContext.","Log the last seen document.cookie value on failure to distinguish 'no token set' from 'token format changed'.","Watch for token-format drift (the `-` guard) and update the matcher if Zhihu changes the token shape."],"tags":["zhihu","anti-bot","wasm","vm","timeout","api-change"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}