{"record":{"id":"1be00e547d4052b5","repo":"jackwener/OpenCLI","slug":"semanticscholar-paper-id-value-is-not-recogni","errorCode":null,"errorMessage":"semanticscholar paper id \"${value}\" is not recognised","messagePattern":"semanticscholar paper id \"(.+?)\" is not recognised","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/semanticscholar/utils.js","lineNumber":77,"sourceCode":"    if (!raw) {\n        throw new ArgumentError(\n            'semanticscholar paper id cannot be empty',\n            'Example: opencli semanticscholar paper 10.18653/v1/N19-1423',\n        );\n    }\n    const s2Url = raw.match(/^https?:\\/\\/(?:www\\.)?semanticscholar\\.org\\/paper\\/(?:[^/]+\\/)?([0-9a-f]{40})/i);\n    if (s2Url) return s2Url[1].toLowerCase();\n    if (S2_PAPER_ID.test(raw)) return raw.toLowerCase();\n    if (PREFIXED.test(raw)) return raw;\n    if (/^doi:/i.test(raw)) {\n        const doi = raw.replace(/^doi:/i, '').trim();\n        if (DOI_BARE.test(doi)) return `DOI:${doi}`;\n    }\n    const doiUrl = raw.match(/^https?:\\/\\/(?:dx\\.)?doi\\.org\\/(.+)$/i);\n    if (doiUrl && DOI_BARE.test(doiUrl[1])) return `DOI:${doiUrl[1]}`;\n    if (DOI_BARE.test(raw)) return `DOI:${raw}`;\n    if (ARXIV_MODERN.test(raw) || ARXIV_LEGACY.test(raw)) return `ARXIV:${raw}`;\n    throw new ArgumentError(\n        `semanticscholar paper id \"${value}\" is not recognised`,\n        'Use a Semantic Scholar paperId, a DOI, an arXiv id, or a prefixed id (e.g. \"ARXIV:1706.03762\", \"PMID:12345\").',\n    );\n}\n\n/**\n * Fetch with optional `SEMANTIC_SCHOLAR_API_KEY` header. Retries once on 429\n * after a short pause; anonymous traffic hits the public ~100 req / 5 min\n * cap, and a single retry covers the typical burst-then-cool-down case.\n */\nexport async function s2Fetch(url, label) {\n    const headers = { 'user-agent': UA, accept: 'application/json' };\n    const apiKey = process.env.SEMANTIC_SCHOLAR_API_KEY;\n    if (apiKey) headers['x-api-key'] = apiKey;\n\n    let resp;\n    let attempt = 0;\n    while (true) {","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/semanticscholar/utils.js#L59-L95","documentation":"requirePaperRef throws ArgumentError when the supplied reference is non-empty but matches none of the supported formats: 40-char hex paperId, Semantic Scholar paper URL, DOI (bare, `doi:`-prefixed, or doi.org URL), arXiv id (modern or legacy), or typed prefixes like ARXIV:/MAG:/ACL:/PMID:/PMCID:/URL:/CorpusId:/DBLP:. The error includes the offending value and lists accepted formats.","triggerScenarios":"Passing a raw paper title, a PubMed URL without PMID: prefix, an ISBN or SSRN id, an arXiv id missing its number part ('arXiv:'), a Semantic Scholar URL whose id is not 40-char hex, or a DOI lacking the `10.` prefix.","commonSituations":"Pasting a citation string instead of an identifier; using a dblp.org or arxiv.org URL rather than the bare id; typos in DOIs (missing '10.'); old Semantic Scholar URLs with a short legacy id.","solutions":["Convert to a supported form: bare DOI (`10.18653/v1/N19-1423`), arXiv id (`1706.03762`), or 40-char Semantic Scholar paperId.","Use a typed prefix for other id systems, e.g. `PMID:12345`, `ACL:N19-1423`, `CorpusId:12345`.","If you only have the title, search first: `opencli semanticscholar search \"<title keywords>\"` and use the returned paperId.","Strip URL noise: for arxiv.org URLs use the id (`2401.01234`); for semanticscholar.org/paper URLs keep only the 40-hex segment."],"exampleFix":"// before\nopencli semanticscholar paper \"https://arxiv.org/abs/1706.03762\"\n// after\nopencli semanticscholar paper \"ARXIV:1706.03762\"","handlingStrategy":"validation","validationCode":"const DOI = /^10\\.\\S+$/;\nconst ARXIV = /^\\d{4}\\.\\d{4,5}(v\\d+)?$/;\nconst S2ID = /^[0-9a-f]{40}$/i;\nfunction looksLikePaperRef(v) {\n    const s = String(v ?? '').trim();\n    return S2ID.test(s) || DOI.test(s) || ARXIV.test(s) || /^(ARXIV|MAG|ACL|PMID|PMCID|URL|CorpusId|DBLP):/i.test(s);\n}","typeGuard":"function isRecognizedPaperRef(v) {\n    const s = String(v ?? '').trim();\n    return /^[0-9a-f]{40}$/i.test(s) || /^10\\.\\S+$/.test(s) || /^\\d{4}\\.\\d{4,5}(v\\d+)?$/.test(s)\n        || /^(ARXIV|MAG|ACL|PMID|PMCID|URL|CorpusId|DBLP):/i.test(s);\n}","tryCatchPattern":"try {\n    await fetchPaper(rawRef);\n} catch (err) {\n    if (err instanceof ArgumentError && /is not recognised/.test(err.message)) {\n        console.error(`${err.message}\\nHint: ${err.suggestion ?? 'use a DOI, arXiv id, or prefixed id'}`);\n        process.exit(2);\n    }\n    throw err;\n}","preventionTips":["Normalize inputs before passing: strip arxiv.org/abs/ URLs to bare ids, keep DOIs starting with 10.","Keep a regex pre-check in scripts that feed ids into the CLI.","Resolve titles via `semanticscholar search` first, then use the returned paperId.","Prefer DOI or arXiv ids (stable, memorable) over opaque 40-hex paperIds."],"tags":["argument-validation","cli","input-format"],"backgroundTag":"invalid-identifier-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}