{"record":{"id":"1bbef0f657acf713","repo":"DIYgod/RSSHub","slug":"invalid-hits-data-received-from-api","errorCode":null,"errorMessage":"Invalid hits data received from API","messagePattern":"Invalid hits data received from API","errorType":"exception","errorClass":"TypeError","httpStatus":503,"severity":"error","filePath":"lib/routes/skeb/search.ts","lineNumber":68,"sourceCode":"                        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":50,"sourceCodeEnd":80,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/skeb/search.ts#L50-L80","documentation":"Thrown as a TypeError specifically when data.results[1].hits exists but is not an array. This is a secondary guard after the primary results-shape check (error 503) passes. The handler accesses results[1] (the 'Request' index results) and then calls .map() on hits, so a non-array hits (e.g. null, an object, a string) would otherwise cause a runtime TypeError on .map() — this throw gives it a descriptive message.","triggerScenarios":"The Algolia 'Request' index returns a result entry whose `hits` field is null or missing. This can happen when the index exists but returned zero hits and Algolia omits the hits array, or when the response schema changed to nest hits under a different key.","commonSituations":"Edge case where the search keyword returns matches in the 'User' index but the 'Request' index returns an empty/degenerate result object; or an Algolia API version change altered the result envelope.","solutions":["Log the full data.results[1] object to inspect its actual shape when the error occurs.","If hits can legitimately be absent, add a fallback: `const works = Array.isArray(data.results[1].hits) ? data.results[1].hits : [];` instead of throwing.","If the Algolia response schema changed, update the data-extraction path to match the new structure."],"exampleFix":"// before\nconst works = data.results[1].hits;\nif (!Array.isArray(works)) {\n    throw new TypeError('Invalid hits data received from API');\n}\n\n// after\nconst works = Array.isArray(data.results[1]?.hits) ? data.results[1].hits : [];\nreturn works.map((item) => processWork(item)).filter(Boolean);","handlingStrategy":"type-guard","validationCode":"const worksResult = data.results[1];\nif (!worksResult || !Array.isArray(worksResult.hits)) {\n    // return empty array instead of throwing for a non-critical missing field\n    return [];\n}","typeGuard":"function isHitsArray(val: unknown): val is unknown[] {\n    return Array.isArray(val);\n}","tryCatchPattern":null,"preventionTips":["Use optional chaining when accessing deeply nested API response fields: data.results[1]?.hits.","Consider returning an empty array for missing search results rather than throwing, since zero search results is a valid user outcome.","Validate each level of a nested response incrementally with descriptive error messages."],"tags":["api","upstream","data-integrity","skeb","search","type-narrowing"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}