{"record":{"id":"022f55649c91f786","repo":"DIYgod/RSSHub","slug":"no-calls-for-papers-found","errorCode":null,"errorMessage":"No Calls for Papers found","messagePattern":"No Calls for Papers found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"lib/routes/sciencedirect/call-for-paper.tsx","lineNumber":46,"sourceCode":"    const apiUrl = `https://www.sciencedirect.com/browse/calls-for-papers?subject=${subject}`;\n    const response = await got(apiUrl);\n    const $ = load(response.body);\n\n    const scriptJSON = $('script[data-iso-key=\"_0\"]').text();\n    if (!scriptJSON) {\n        throw new Error('Cannot find the script with data-iso-key=\"_0\"');\n    }\n\n    let data;\n    try {\n        data = JSON.parse(JSON.parse(scriptJSON));\n    } catch (error: any) {\n        throw new Error(`Failed to parse embedded script JSON: ${error.message}`, { cause: error });\n    }\n\n    const cfpList = data?.callsForPapers?.list || [];\n    if (!cfpList.length) {\n        throw new Error('No Calls for Papers found');\n    }\n\n    const items = cfpList.map((cfp) => {\n        const link = `https://www.sciencedirect.com/special-issue/${cfp.contentId}/${cfp.url}`;\n        const description = renderToString(\n            <div>\n                <p>\n                    <strong>Summary:</strong> {cfp.summary}\n                </p>\n                <p>\n                    <strong>Submission Deadline:</strong> {cfp.submissionDeadline}\n                </p>\n                <p>\n                    <strong>Journal:</strong> {`${cfp.journal.displayName} (IF: ${cfp.journal.impactFactor}, CiteScore: ${cfp.journal.citeScore})`}\n                </p>\n            </div>\n        );\n","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/sciencedirect/call-for-paper.tsx#L28-L64","documentation":"Thrown when the parsed ScienceDirect payload parses successfully but contains no callsForPapers.list entries (the array is empty or the path is absent). It distinguishes a structural failure (no script / bad JSON) from a legitimately-empty result for the requested subject.","triggerScenarios":"data.callsForPapers.list is undefined/null/[] after successful parsing. This happens when the subject has no open calls for papers, or when ScienceDirect moved the list to a different JSON path.","commonSituations":"A subject slug with no current special issues; the JSON key was renamed (e.g. callsForPapers -> cfps) so the optional chaining yields nothing; all calls for that subject expired and were pruned.","solutions":["Open the URL in a browser and confirm whether calls for that subject actually exist today.","If calls exist but the path changed, update data.callsForPapers.list to the new location in the parsed payload.","Try a known-busy subject (e.g. 'education') to verify the path is correct.","If empty is a valid state, consider returning an allowEmpty feed instead of throwing."],"exampleFix":"// before\nconst cfpList = data?.callsForPapers?.list || [];\nif (!cfpList.length) {\n    throw new Error('No Calls for Papers found');\n}\n\n// after — return an empty feed (with allowEmpty) instead of erroring when the subject genuinely has none\nconst cfpList = data?.callsForPapers?.list || [];\nif (!cfpList.length) {\n    return { title: `ScienceDirect Calls for Papers - ${subject}`, description: 'No open calls for papers.', link: apiUrl, item: [], allowEmpty: true };\n}","handlingStrategy":"fallback","validationCode":"// Treat an empty callsForPapers list as an empty feed, not an error, when the subject is valid.\nconst cfpList = data?.callsForPapers?.list ?? [];\nif (!cfpList.length) {\n    return { title: `...`, item: [], allowEmpty: true } as Data;\n}","typeGuard":"const hasCfpList = (d: unknown): d is { callsForPapers: { list: unknown[] } } =>\n    isPlainObject(d) && Array.isArray((d as any)?.callsForPapers?.list) && (d as any).callsForPapers.list.length > 0;","tryCatchPattern":"try {\n    return await handler(ctx);\n} catch (e) {\n    if (e instanceof Error && /No Calls for Papers found/.test(e.message)) {\n        // return an empty-but-valid feed instead of a hard failure\n        return { title: `ScienceDirect Calls for Papers - ${subject}`, item: [], allowEmpty: true };\n    }\n    throw e;\n}","preventionTips":["Distinguish 'no calls right now' (empty, valid) from 'payload path changed' (structural failure).","Pin the JSON path (data.callsForPapers.list) with a snapshot test.","Set allowEmpty: true when an empty result is a legitimate state."],"tags":["data-validation","upstream-change","json-parsing","sciencedirect","empty-result"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}