{"record":{"id":"e2a6ff219e552db4","repo":"jackwener/OpenCLI","slug":"subtitle-url-cli","errorCode":null,"errorMessage":"[风控拦截/未登录] 获取到的 subtitle_url 为空！请确保 CLI 已成功登录且风控未封锁此账号。","messagePattern":"\\[风控拦截/未登录\\] 获取到的 subtitle_url 为空！请确保 CLI 已成功登录且风控未封锁此账号。","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/subtitle.js","lineNumber":78,"sourceCode":"        if (!Array.isArray(subtitles)) {\n            throw new CommandExecutionError('获取到的字幕列表对象不符合数组格式');\n        }\n        if (subtitles.length === 0) {\n            if (needLoginSubtitle) {\n                throw new AuthRequiredError('bilibili.com', 'Bilibili subtitles are hidden behind login for this video. Please log in to bilibili.com in Chrome and retry.');\n            }\n            throw new EmptyResultError('bilibili subtitle', '此视频没有发现外挂或智能字幕。');\n        }\n        // 3. 选择目标字幕语言\n        const target = kwargs.lang\n            ? subtitles.find((s) => s.lan === kwargs.lang) || subtitles[0]\n            : subtitles[0];\n        if (!target || typeof target !== 'object' || !Object.hasOwn(target, 'subtitle_url')) {\n            throw new CommandExecutionError('字幕条目缺少 subtitle_url 字段');\n        }\n        const targetSubUrl = typeof target.subtitle_url === 'string' ? target.subtitle_url.trim() : '';\n        if (!targetSubUrl) {\n            throw new AuthRequiredError('bilibili.com', '[风控拦截/未登录] 获取到的 subtitle_url 为空！请确保 CLI 已成功登录且风控未封锁此账号。');\n        }\n        const finalUrl = targetSubUrl.startsWith('//') ? 'https:' + targetSubUrl : targetSubUrl;\n        if (!/^https?:\\/\\//i.test(finalUrl)) {\n            throw new CommandExecutionError(`字幕 URL 非法: ${finalUrl}`);\n        }\n        // 4. 解析并拉取 CDN 的 JSON 文件\n        const fetchJs = `\n      (async () => {\n         const url = ${JSON.stringify(finalUrl)};\n         const res = await fetch(url);\n         const text = await res.text();\n\n         if (text.startsWith('<!DOCTYPE') || text.startsWith('<html')) {\n            return { error: 'HTML', text: text.substring(0, 100), url };\n         }\n\n         try {\n             const subJson = JSON.parse(text);","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/subtitle.js#L60-L96","documentation":"An AuthRequiredError thrown when the selected subtitle track has a subtitle_url field but its value is empty or whitespace after trimming. Bilibili deliberately returns an empty URL when the request is blocked by risk control (风控) or the session is not logged in, so this is a signal about account/session state, not data corruption.","triggerScenarios":"subtitle_url is '' or non-string (null) on the chosen track — typically when the CLI's Chrome session is not logged into bilibili.com or the account/IP is rate-limited or flagged by Bilibili's risk-control system.","commonSituations":"Running the CLI without having logged into bilibili.com in Chrome; scraping many videos quickly and triggering rate limiting; using a datacenter IP or VPN that Bilibili blocks; expired login cookies.","solutions":["Open bilibili.com in Chrome and log in, then retry the CLI (it drives the same Chrome profile).","Wait and retry later if you hit risk control from too many rapid requests.","Reduce request rate / batch size, or switch to a residential IP instead of VPN/datacenter.","Log out and back in to refresh cookies if the session is stale."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-check: ensure a Chrome profile logged into bilibili.com exists before invoking the CLI.","typeGuard":null,"tryCatchPattern":"try {\n  await run('bilibili subtitle', { url });\n} catch (e) {\n  if (e.name === 'AuthRequiredError' || /风控|未登录/.test(e.message)) {\n    await backoff(60_000);\n    return run('bilibili subtitle', { url }); // after login/cool-down\n  }\n  throw e;\n}","preventionTips":["Log in to bilibili.com in Chrome before running batch jobs.","Throttle request rate to avoid Bilibili risk control.","Avoid VPN/datacenter IPs for bilibili.com automation.","Refresh login cookies if the session is old."],"tags":["bilibili","auth","risk-control","rate-limit"],"backgroundTag":"auth-required-login","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}