jackwener/OpenCLI · error · CommandExecutionError
semanticscholar ${label} must be a number when present
Error message
semanticscholar ${label} must be a number when present What it means
optionalNumber validates that an optional numeric field (year, citationCount) on a Semantic Scholar paper row is either null/undefined or a finite number. If the field is present but is a string, NaN, or Infinity, it throws this CommandExecutionError naming the field via `label`. It enforces the adapter's typed-row contract before output.
Source
Thrown at clis/semanticscholar/utils.js:157
return tldr.text.trim();
}
return '';
}
/** First author display name, or '' when authors is missing. */
export function firstAuthorName(authors) {
if (!Array.isArray(authors) || !authors.length) return '';
const first = authors[0];
if (first && typeof first === 'object' && typeof first.name === 'string') {
return first.name.trim();
}
return '';
}
export function optionalNumber(value, label) {
if (value == null) return null;
if (typeof value !== 'number' || !Number.isFinite(value)) {
throw new CommandExecutionError(`semanticscholar ${label} must be a number when present`);
}
return value;
}
export function normalizePaperRow(paper, label, { rank } = {}) {
if (!paper || typeof paper !== 'object') {
throw new CommandExecutionError(`semanticscholar ${label} row is not an object`);
}
if (typeof paper.paperId !== 'string' || !paper.paperId.trim()) {
throw new CommandExecutionError(`semanticscholar ${label} row is missing paperId`);
}
if (typeof paper.title !== 'string' || !paper.title.trim()) {
throw new CommandExecutionError(`semanticscholar ${label} row is missing title`);
}
if (paper.authors != null && !Array.isArray(paper.authors)) {
throw new CommandExecutionError(`semanticscholar ${label} row has malformed authors`);
}
const row = {View on GitHub (pinned to 49907e53dc)
Solutions
- Coerce numeric strings before passing through: Number(value) and re-check Number.isFinite.
- Check which field the label names (e.g. `${label} year`) and inspect the raw API response for that field.
- If the API changed shape, pin/upgrade the adapter version that matches the current schema.
- Sanitize upstream data sources feeding normalizePaperRow.
Example fix
// before: strict pass-through
year: optionalNumber(paper.year, `${label} year`),
// after: coerce numeric strings first
const year = paper.year == null ? null : (typeof paper.year === 'string' && paper.year.trim() !== '' ? Number(paper.year) : paper.year);
year: optionalNumber(year, `${label} year`), Defensive patterns
Strategy: validation
Validate before calling
function toFiniteNumberOrNull(v) {
if (v == null) return null;
const n = typeof v === 'number' ? v : Number(v);
return Number.isFinite(n) ? n : null;
}
// apply before calling the API-consuming code path
const year = toFiniteNumberOrNull(rawPaper.year); Type guard
function isFiniteNumber(v) {
return typeof v === 'number' && Number.isFinite(v);
} Try / catch
try {
const row = normalizePaperRow(paper, 'citation');
} catch (err) {
if (/must be a number when present/.test(err.message)) {
return null; // skip malformed numeric field
}
throw err;
} Prevention
- Coerce numeric strings from upstream sources before normalization.
- Pin the adapter version against the S2 API schema you test with.
- Sanitize fixtures used in scripts to use real numbers.
When it happens
Trigger: normalizePaperRow passes paper.year or paper.citationCount to optionalNumber and the API returned a non-numeric value — e.g. year as a string "2023", citationCount as null-coalesced garbage, or a dataset row with corrupted fields.
Common situations: Semantic Scholar API schema changes returning strings for numeric fields; third-party/proxied responses with stringified numbers; hand-built test fixtures with string values.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- semanticscholar ${label} row is not an object
- semanticscholar ${label} row has malformed authors
- ${label} returned an unexpected payload shape; expected an o
- ${label} returned an unexpected payload shape; expected an a
- ${label} did not include a stable ${field}.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0b5f38b71b8a743b.
Report an issue: GitHub.