{"record":{"id":"bd664559bdb11f37","repo":"jackwener/OpenCLI","slug":"semantic-scholar-returned-404-for-url","errorCode":null,"errorMessage":"Semantic Scholar returned 404 for ${url}.","messagePattern":"Semantic Scholar returned 404 for (.+?)\\.","errorType":"exception","errorClass":"EmptyResultError","httpStatus":404,"severity":"warning","filePath":"clis/semanticscholar/utils.js","lineNumber":113,"sourceCode":"    while (true) {\n        try {\n            resp = await fetch(url, { headers });\n        } catch (err) {\n            throw new CommandExecutionError(\n                `${label} request failed: ${err?.message ?? err}`,\n                'Check that api.semanticscholar.org is reachable from this network.',\n            );\n        }\n        if (resp.status === 429 && attempt === 0 && !apiKey) {\n            attempt += 1;\n            await new Promise(resolve => setTimeout(resolve, 1500));\n            continue;\n        }\n        break;\n    }\n\n    if (resp.status === 404) {\n        throw new EmptyResultError(label, `Semantic Scholar returned 404 for ${url}.`);\n    }\n    if (resp.status === 429) {\n        throw new CommandExecutionError(\n            `${label} returned HTTP 429 (rate limited)`,\n            'Semantic Scholar throttles anonymous traffic; set SEMANTIC_SCHOLAR_API_KEY (free at https://www.semanticscholar.org/product/api) or wait a minute and retry.',\n        );\n    }\n    if (!resp.ok) {\n        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);\n    }\n    let body;\n    try {\n        body = await resp.json();\n    } catch (err) {\n        throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);\n    }\n    if (body && typeof body === 'object' && body.error) {\n        throw new CommandExecutionError(`${label} returned an error: ${body.error}`);","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/semanticscholar/utils.js#L95-L131","documentation":"s2Fetch maps an HTTP 404 from the Semantic Scholar API to EmptyResultError with the full request URL in the message. Semantically, 404 means the requested resource (paper id, citation set, recommendation set) does not exist, so the library treats it as an empty result rather than a hard failure — enabling uniform no-data handling in scripts.","triggerScenarios":"Calling `paper`/`citations`/`recommendations` with an id the API cannot resolve: a typo in a 40-hex paperId, a deleted/merged paper, an ARXIV:/DOI:/PMID: id that Semantic Scholar has no record for, or a CorpusId that does not exist.","commonSituations":"Hardcoded ids copied from another database (MAG ids retired after MAG shutdown); stale cached paperIds; DOIs of papers never ingested by Semantic Scholar; scripts feeding ids from an outdated export.","solutions":["Validate the reference: re-run `opencli semanticscholar search \"<title>\"` and use the paperId from results.","Double-check the id for typos and that it is currently valid (try the DOI or arXiv form instead).","If using a typed prefix, confirm the id under that prefix exists (e.g. PMID ids must exist in PubMed).","In scripts, catch EmptyResultError and skip/log the id instead of aborting."],"exampleFix":"// before\nopencli semanticscholar paper \"10.9999/nonexistent-doi\"\n// after\nopencli semanticscholar search \"Attention Is All You Need\"\nopencli semanticscholar paper \"ARXIV:1706.03762\"","handlingStrategy":"try-catch","validationCode":"// validate ref format before calling (avoids most 404s)\nif (!isRecognizedPaperRef(ref)) throw new Error(`unrecognized paper ref: ${ref}`);","typeGuard":null,"tryCatchPattern":"try {\n    const paper = await fetchPaper(ref);\n} catch (err) {\n    if (err instanceof EmptyResultError) {\n        console.warn(`Not found on Semantic Scholar: ${ref}; skipping.`);\n        return null;\n    }\n    throw err;\n}","preventionTips":["Resolve references through `semanticscholar search` instead of trusting external id databases.","Watch for retired id spaces (MAG ids) and stale cached paperIds in your data.","Log the URL from the error message to confirm which id 404'd.","Maintain a skip-list of ids that repeatedly 404 in batch jobs."],"tags":["http-404","empty-results","api"],"backgroundTag":"http-404-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}