{"record":{"id":"3c9a94366eb77cb5","repo":"DIYgod/RSSHub","slug":"key-not-found","errorCode":null,"errorMessage":"Key not found.","messagePattern":"Key not found\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/scoop/apps.tsx","lineNumber":62,"sourceCode":"    const targetResponse = await ofetch(targetUrl);\n    const $: CheerioAPI = load(targetResponse);\n    const language = $('html').attr('lang') ?? 'en';\n\n    const scriptRegExp = /<script type=\"module\" crossorigin src=\"(.*?)\"><\\/script>/;\n    const scriptUrl: string = scriptRegExp.test(targetResponse) ? new URL(targetResponse.match(scriptRegExp)?.[1], baseUrl).href : '';\n\n    if (!scriptUrl) {\n        throw new Error('JavaScript file not found.');\n    }\n\n    const scriptResponse = await ofetch(scriptUrl, {\n        parseResponse: (txt) => txt,\n    });\n\n    const key: string = scriptResponse.match(/VITE_APP_AZURESEARCH_KEY:\"(.*?)\"/)?.[1];\n\n    if (!key) {\n        throw new Error('Key not found.');\n    }\n\n    const isOffcial = !query.includes('o=false');\n    const isDistinct = !query.includes('dm=false');\n    const sort: string = query.match(/s=(\\d+)/)?.[1] ?? '2';\n    const desc: string = query.match(/d=(\\d+)/)?.[1] ?? '1';\n\n    const response = await ofetch(apiUrl, {\n        method: 'post',\n        query: {\n            'api-version': '2020-06-30',\n        },\n        headers: {\n            'api-key': key,\n            origin: baseUrl,\n            referer: baseUrl,\n        },\n        body: {","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/scoop/apps.tsx#L44-L80","documentation":"Thrown when the scoop.sh JS bundle is fetched but the regex for VITE_APP_AZURESEARCH_KEY does not match, so no Azure Search query key can be recovered. Without the key the subsequent POST to the Azure Search index cannot authenticate, so the route aborts.","triggerScenarios":"scriptResponse (the JS bundle text) does not contain the substring VITE_APP_AZURESEARCH_KEY:\"...\" — the env var was renamed, the bundle is now minified differently, or the key is injected at runtime instead of baked into the bundle.","commonSituations":"scoop.sh rotated/renamed its Vite env var (e.g. VITE_APP_AZURESEARCH_KEY -> VITE_AZURE_SEARCH_KEY); the build now inlines the key under a different identifier; a sourcemap/deobfuscation change altered the literal.","solutions":["Download the current JS bundle and grep for 'AZURESEARCH' / 'api-key' to find the new identifier.","Update the regex on line 59 to the new var name/pattern.","If the key is now fetched at runtime (an XHR to a token endpoint), replicate that request instead of scraping the bundle.","If scoop.sh stopped exposing a public search key entirely, the route needs a different auth strategy."],"exampleFix":"// before\nconst key: string = scriptResponse.match(/VITE_APP_AZURESEARCH_KEY:\"(.*?)\"/)?.[1];\nif (!key) {\n    throw new Error('Key not found.');\n}\n\n// after — try several known identifier shapes\nconst key: string =\n    scriptResponse.match(/VITE_APP_AZURESEARCH_KEY:\"(.*?)\"/)?.[1] ||\n    scriptResponse.match(/VITE_AZURE_SEARCH_KEY:\"(.*?)\"/)?.[1] ||\n    scriptResponse.match(/[\"']?apiKey[\"']?\\s*[:=]\\s*[\"']([A-Za-z0-9]+)[\"']/)?.[1] ||\n    '';\nif (!key) {\n    throw new Error('Azure Search key not found in scoop.sh bundle (identifier may have been renamed).');\n}","handlingStrategy":"fallback","validationCode":"// Try several known identifier shapes for the Azure Search key.\nfunction extractAzureKey(bundle: string): string {\n    return (\n        bundle.match(/VITE_APP_AZURESEARCH_KEY:\"(.*?)\"/)?.[1] ||\n        bundle.match(/VITE_AZURE_SEARCH_KEY:\"(.*?)\"/)?.[1] ||\n        bundle.match(/AZURESEARCH_KEY:\"(.*?)\"/)?.[1] ||\n        ''\n    );\n}","typeGuard":"const looksLikeAzureKey = (k: string | undefined): k is string =>\n    typeof k === 'string' && /^[A-Za-z0-9+/=]{20,}$/.test(k);","tryCatchPattern":"let key = extractAzureKey(scriptResponse);\nif (!key) {\n    // re-fetch the bundle (it may have been a stale CDN copy) and retry\n    const fresh = await ofetch(scriptUrl, { parseResponse: (t) => t });\n    key = extractAzureKey(fresh);\n}\nif (!key) throw new Error('Azure Search key not found in scoop.sh bundle (identifier may have been renamed).');","preventionTips":["Maintain a list of historical identifier names for the key so renames are tolerated.","If scoop.sh moves to a runtime-token model, replicate the token request instead of scraping.","Log the matched identifier so a future rename is self-documenting."],"tags":["scraping","upstream-change","regex","api-key","scoop"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}