{"record":{"id":"5d146ed7cbd73e72","repo":"DIYgod/RSSHub","slug":"invalid-data-received-from-api-5d146e","errorCode":null,"errorMessage":"Invalid data received from API","messagePattern":"Invalid data received from API","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"error","filePath":"lib/routes/skeb/search.ts","lineNumber":62,"sourceCode":"            body: {\n                requests: [\n                    {\n                        indexName: 'User',\n                        query: keyword,\n                        params: 'hitsPerPage=40',\n                        filters: 'genres:art OR genres:comic OR genres:voice OR genres:novel OR genres:video OR genres:music OR genres:correction',\n                    },\n                    {\n                        indexName: 'Request',\n                        query: keyword,\n                        params: 'hitsPerPage=40&filters=genre%3Aart%20OR%20genre%3Acomic%20OR%20genre%3Avoice%20OR%20genre%3Anovel%20OR%20genre%3Avideo%20OR%20genre%3Amusic%20OR%20genre%3Acorrection',\n                    },\n                ],\n            },\n        });\n\n        if (!data || !data.results || !Array.isArray(data.results) || data.results.length < 2) {\n            throw new Error('Invalid data received from API');\n        }\n\n        const works = data.results[1].hits;\n\n        if (!Array.isArray(works)) {\n            throw new TypeError('Invalid hits data received from API');\n        }\n\n        return works.map((item) => processWork(item)).filter(Boolean);\n    });\n\n    return {\n        title: `Skeb - Search Results for \"${keyword}\"`,\n        link: `${baseUrl}/search?q=${encodeURIComponent(keyword)}`,\n        item: items as DataItem[],\n    };\n}\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/skeb/search.ts#L44-L80","documentation":"Thrown as a plain Error when the Algolia multi-query search API response is malformed: either the top-level `data` is falsy, `data.results` is missing/not-an-array, or the results array has fewer than 2 entries. The handler sends two parallel queries (indexName 'User' and 'Request') and indexes into results[1] for works, so it requires at least 2 result entries. This guard prevents an out-of-bounds or undefined-property access downstream.","triggerScenarios":"The Algolia endpoint returns an error object instead of the expected { results: [...] } shape; one of the two requested indexes ('User' or 'Request') was renamed or deleted by Skeb; or the hardcoded API key was revoked, causing Algolia to return an error JSON like { message: 'Invalid API Key' } that lacks a results array.","commonSituations":"Skeb rotated their Algolia API key (hardcoded as x-algolia-api-key in the source); Skeb migrated away from Algolia to a different search backend; or Algolia rate-limited the endpoint returning a throttled response.","solutions":["Inspect the raw Algolia response by replaying the POST to https://hb1jt3kre9-dsn.algolia.net/1/indexes/*/queries with the current headers to see the error body.","If the API key was revoked, extract the new Algolia application-id and api-key from the Skeb website's network requests and update the hardcoded headers in search.ts.","If Skeb changed their search provider, the route needs to be rewritten to use the new search endpoint.","If this is transient (Algolia rate limit), retry after a short delay or reduce request frequency."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"if (!data || typeof data !== 'object') throw new Error('Invalid data from Algolia');\nif (!('results' in data) || !Array.isArray(data.results) || data.results.length < 2) {\n    throw new Error('Algolia search returned insufficient results');\n}","typeGuard":"interface AlgoliaMultiQueryResponse {\n    results: Array<{ hits: unknown[] }>;\n}\nfunction isAlgoliaResponse(data: unknown): data is AlgoliaMultiQueryResponse {\n    return (\n        data !== null &&\n        typeof data === 'object' &&\n        'results' in data &&\n        Array.isArray((data as any).results) &&\n        (data as any).results.length >= 2\n    );\n}","tryCatchPattern":"try {\n    const data = await ofetch(url, { /* ... */ });\n    if (!isAlgoliaResponse(data)) throw new Error('Invalid data received from API');\n    const works = data.results[1].hits;\n} catch (e) {\n    logger.error('Algolia search failed', e);\n    throw e;\n}","preventionTips":["Do not hardcode third-party API keys; extract them dynamically from the source website if possible.","Add response schema validation using a runtime type checker (e.g. zod) for complex API responses.","Log the full Algolia error body when validation fails to aid debugging."],"tags":["api","upstream","search","algolia","data-integrity","skeb"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}