jackwener/OpenCLI · error · ArgumentError
openalex work id "${value}" must be a Work (W…) ID, got "${i
Error message
openalex work id "${value}" must be a Work (W…) ID, got "${id[0]}…" What it means
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.
Source
Thrown at clis/openalex/utils.js:53
return n;
}
/**
* Resolve a user-supplied work identifier to OpenAlex's canonical path
* segment. Accepts `W…` IDs, `doi:10.…`, raw DOIs, or full
* `https://doi.org/…` / `https://openalex.org/W…` URLs.
*/
export function requireWorkRef(value) {
const raw = String(value ?? '').trim();
if (!raw) {
throw new ArgumentError('openalex work id is required (e.g. "W2741809807", "10.7717/peerj.4375")');
}
// 1) full openalex URL
const oaUrl = raw.match(/^https?:\/\/(?:api\.)?openalex\.org\/(?:works\/)?([WAaSCFwIPwT]\d+)/i);
if (oaUrl) {
const id = oaUrl[1].toUpperCase();
if (id[0] !== 'W') {
throw new ArgumentError(`openalex work id "${value}" must be a Work (W…) ID, got "${id[0]}…"`);
}
return id;
}
// 2) bare W… id
if (WORK_ID.test(raw.toUpperCase())) {
return raw.toUpperCase();
}
// 3) doi:… prefix
if (/^doi:/i.test(raw)) {
const doi = raw.replace(/^doi:/i, '').trim();
if (DOI_BARE.test(doi)) return `doi:${doi}`;
}
// 4) full doi URL
const doiUrl = raw.match(/^https?:\/\/(?:dx\.)?doi\.org\/(.+)$/i);
if (doiUrl && DOI_BARE.test(doiUrl[1])) {
return `doi:${doiUrl[1]}`;
}
// 5) bare 10.xxxx/yyy DOIView on GitHub (pinned to 49907e53dc)
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
Example fix
// before
await work('https://openalex.org/A5023888391'); // author URL
// after
await work('https://openalex.org/W2741809807'); // work URL (or '10.7717/peerj.4375') Defensive patterns
Strategy: validation
Validate before calling
function extractWorkIdFromUrl(url) {
const m = String(url).match(/openalex\.org\/(?:works\/)?([A-Z]\d+)/i);
if (!m) return null;
const id = m[1].toUpperCase();
if (id[0] !== 'W') throw new Error(`URL is an ${id[0]}-entity, need a W (work) URL`);
return id;
} Type guard
function isWorkId(id) {
return typeof id === 'string' && /^W\d{4,}$/.test(id.trim().toUpperCase());
} Try / catch
try {
await work(ref);
} catch (e) {
if (e.name === 'ArgumentError' && e.message.includes('must be a Work')) {
console.error('That OpenAlex URL is not a work; use the W… id or the DOI'); process.exitCode = 2;
} else throw e;
} Prevention
- 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
When it happens
Trigger: 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'.
Common situations: 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.
Related errors
- openalex ${label} cannot be empty
- openalex ${label} must be a positive integer
- openalex ${label} must be <= ${maxValue}
- openalex work id is required (e.g. "W2741809807", "10.7717/p
- openalex work id "${value}" is not recognised
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/9519bdca68ce25d0.
Report an issue: GitHub.