{"record":{"id":"d74b3afb4ad05dba","repo":"DIYgod/RSSHub","slug":"failed-to-extract-algolia-credentials-from-iapp-or","errorCode":null,"errorMessage":"Failed to extract Algolia credentials from iapp.org","messagePattern":"Failed to extract Algolia credentials from iapp\\.org","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/iapp/news.ts","lineNumber":46,"sourceCode":"    const baseUrl = 'https://iapp.org';\n    const link = `${baseUrl}/news`;\n\n    const { appId, apiKey, description } = await cache.tryGet('iapp:algolia-credentials', async () => {\n        const html = await ofetch(link);\n        const $ = load(html);\n        let appId: string | undefined;\n        let apiKey: string | undefined;\n        $('script').each((_, el) => {\n            const text = $(el).text();\n            const match = text.match(/\\\\\"appID\\\\\":\\\\\"(\\w+)\\\\\",\\\\\"apiKey\\\\\":\\\\\"(\\w+)\\\\\"/);\n            if (match) {\n                appId = match[1];\n                apiKey = match[2];\n                return false;\n            }\n        });\n        if (!appId || !apiKey) {\n            throw new Error('Failed to extract Algolia credentials from iapp.org');\n        }\n        return {\n            appId,\n            apiKey,\n            description: $('meta[name=\"description\"]').attr('content'),\n        };\n    });\n\n    const response = await ofetch(`https://${appId.toLowerCase()}-dsn.algolia.net/1/indexes/*/queries`, {\n        method: 'POST',\n        query: {\n            'x-algolia-api-key': apiKey,\n            'x-algolia-application-id': appId,\n        },\n        headers: {\n            Referer: `${baseUrl}/`,\n        },\n        body: {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/iapp/news.ts#L28-L64","documentation":"Thrown by the IAPP news route when the handler cannot extract Algolia `appID` and `apiKey` from the iapp.org homepage HTML. The route scrapes the page's `<script>` tags looking for a specific escaped JSON pattern (`\\\"appID\\\":\\\"...\\\",\\\"apiKey\\\":\\\"...\\\"`). If iapp.org changes its JavaScript bundling, renames the keys, changes the escaping, or stops embedding credentials client-side, the regex will not match.","triggerScenarios":"The iapp.org homepage no longer embeds Algolia credentials in the expected format. The credentials are cached under `iapp:algolia-credentials`, so the error first appears after the cache expires. The regex at line 38 is brittle and depends on the exact escaping of the JSON within the script tag.","commonSituations":"IAPP updates their Next.js/Astro build pipeline changing how the Algolia config is serialized, they move to server-side search proxying (removing client-side credentials), they rename the config keys, or the escaping changes from `\\\"` to `\"` or template literals.","solutions":["Open `https://iapp.org/news` in a browser, view page source, and search for `appID` and `apiKey` to see the current format.","Update the regex at line 38 to match the new format (e.g. adjust escape patterns, handle different quote styles, or switch to a JSON parsing approach).","Clear the `iapp:algolia-credentials` cache key after deploying a fix.","If credentials are no longer client-side, switch to a server-side API endpoint or a different data source."],"exampleFix":"// before (brittle regex tied to specific escaping)\nconst match = text.match(/\\\\\"appID\\\\\":\\\\\"(\\\\w+)\\\\\",\\\\\"apiKey\\\\\":\\\\\"(\\\\w+)\\\\\"/);\n\n// after (more robust: handle multiple escaping styles)\nconst match = text.match(/appID[\":\\\\\\s]+([A-Z0-9]+)[\"\\\\\\s,]+apiKey[\":\\\\\\s]+([a-f0-9]+)/i);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function hasAlgoliaCredentials(html: string): boolean {\n    return /appID/.test(html) && /apiKey/.test(html);\n}","tryCatchPattern":"try {\n    const $ = load(html);\n    // ... regex extraction\n    if (!appId || !apiKey) {\n        throw new Error('Failed to extract Algolia credentials from iapp.org');\n    }\n} catch (err) {\n    throw new Error(`iapp.org credential extraction failed: ${err instanceof Error ? err.message : String(err)}`);\n}","preventionTips":["Cache extracted credentials with a TTL to reduce scraping frequency.","Make the extraction regex robust against different escaping styles.","Periodically verify the iapp.org homepage structure hasn't changed.","Fall back to an alternative data source if client-side credentials are removed."],"tags":["upstream","parsing","scraping","config-drift","rsshub","new-media"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}