{"record":{"id":"9519bdca68ce25d0","repo":"jackwener/OpenCLI","slug":"openalex-work-id-value-must-be-a-work-w-id","errorCode":null,"errorMessage":"openalex work id \"${value}\" must be a Work (W…) ID, got \"${id[0]}…\"","messagePattern":"openalex work id \"(.+?)\" must be a Work \\(W…\\) ID, got \"(.+?)…\"","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/openalex/utils.js","lineNumber":53,"sourceCode":"    return n;\n}\n\n/**\n * Resolve a user-supplied work identifier to OpenAlex's canonical path\n * segment. Accepts `W…` IDs, `doi:10.…`, raw DOIs, or full\n * `https://doi.org/…` / `https://openalex.org/W…` URLs.\n */\nexport function requireWorkRef(value) {\n    const raw = String(value ?? '').trim();\n    if (!raw) {\n        throw new ArgumentError('openalex work id is required (e.g. \"W2741809807\", \"10.7717/peerj.4375\")');\n    }\n    // 1) full openalex URL\n    const oaUrl = raw.match(/^https?:\\/\\/(?:api\\.)?openalex\\.org\\/(?:works\\/)?([WAaSCFwIPwT]\\d+)/i);\n    if (oaUrl) {\n        const id = oaUrl[1].toUpperCase();\n        if (id[0] !== 'W') {\n            throw new ArgumentError(`openalex work id \"${value}\" must be a Work (W…) ID, got \"${id[0]}…\"`);\n        }\n        return id;\n    }\n    // 2) bare W… id\n    if (WORK_ID.test(raw.toUpperCase())) {\n        return raw.toUpperCase();\n    }\n    // 3) doi:… prefix\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    // 4) full doi URL\n    const doiUrl = raw.match(/^https?:\\/\\/(?:dx\\.)?doi\\.org\\/(.+)$/i);\n    if (doiUrl && DOI_BARE.test(doiUrl[1])) {\n        return `doi:${doiUrl[1]}`;\n    }\n    // 5) bare 10.xxxx/yyy DOI","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/openalex/utils.js#L35-L71","documentation":"When requireWorkRef is given a full openalex.org or api.openalex.org URL, it extracts the entity ID and requires it to be a Work (W…) ID; any other entity type (A authors, S sources, I institutions, etc.) throws this ArgumentError. The library only supports work lookups, so a valid but wrong-kind OpenAlex ID is rejected with both the original input and the offending prefix in the message.","triggerScenarios":"Passing a URL like https://openalex.org/A5088555860 (author) or https://openalex.org/S123456 (source) — the regex matches the ID but the first character is not 'W'.","commonSituations":"Copying a link from an OpenAlex author or institution page instead of the work page; confusing OpenAlex IDs with DOI-based lookups; mixing up entity types when scripting over OpenAlex pages.","solutions":["Use the W… ID of the work itself (from the work's OpenAlex page URL) or its DOI","If you actually have an author/source, use the corresponding authors/sources command instead of the work endpoint","Strip to the W-id portion or replace the URL with the DOI link from the work's page"],"exampleFix":"// before\nawait work('https://openalex.org/A5023888391'); // author URL\n// after\nawait work('https://openalex.org/W2741809807'); // work URL (or '10.7717/peerj.4375')","handlingStrategy":"validation","validationCode":"function extractWorkIdFromUrl(url) {\n  const m = String(url).match(/openalex\\.org\\/(?:works\\/)?([A-Z]\\d+)/i);\n  if (!m) return null;\n  const id = m[1].toUpperCase();\n  if (id[0] !== 'W') throw new Error(`URL is an ${id[0]}-entity, need a W (work) URL`);\n  return id;\n}","typeGuard":"function isWorkId(id) {\n  return typeof id === 'string' && /^W\\d{4,}$/.test(id.trim().toUpperCase());\n}","tryCatchPattern":"try {\n  await work(ref);\n} catch (e) {\n  if (e.name === 'ArgumentError' && e.message.includes('must be a Work')) {\n    console.error('That OpenAlex URL is not a work; use the W… id or the DOI'); process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Only copy URLs from OpenAlex work pages (path starts with /W…)","Prefer passing the DOI — it is unambiguous","Check the first letter of the ID: W=work, A=author, S=source, I=institution"],"tags":["openalex","argument-validation","wrong-entity-type"],"backgroundTag":"invalid-resource-id","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}