jackwener/OpenCLI · error · CommandExecutionError
semanticscholar ${label} row has malformed authors
Error message
semanticscholar ${label} row has malformed authors What it means
normalizePaperRow tolerates a missing authors field but rejects one that is present and not an array (`paper.authors != null && !Array.isArray(paper.authors)`), throwing this CommandExecutionError. It enforces that author data, when supplied, follows the expected [{name: string}] shape.
Source
Thrown at clis/semanticscholar/utils.js:173
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 = {
paperId: paper.paperId.trim(),
doi: pickDoi(paper.externalIds),
title: paper.title.trim(),
year: optionalNumber(paper.year, `${label} year`),
firstAuthor: firstAuthorName(paper.authors),
citationCount: optionalNumber(paper.citationCount, `${label} citationCount`),
url: typeof paper.url === 'string' && paper.url.trim()
? paper.url.trim()
: `https://www.semanticscholar.org/paper/${paper.paperId.trim()}`,
};
if (rank != null) return { rank, ...row };
return row;
}
/** Strip the typed prefix from `externalIds.DOI` and similar. */
export function pickDoi(externalIds) {View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the raw row's authors value and conform the fixture/caller to an array of {name} objects.
- Coerce common shapes: wrap a single author string in [{name: s}] or extract Object.values if it's an object map.
- Check for API version changes and update the adapter's field handling.
- Drop the malformed field (set authors to null) so firstAuthorName returns '' instead of failing.
Example fix
// before
authors: paper.authors,
// after: coerce or null out malformed authors
let authors = paper.authors;
if (authors != null && !Array.isArray(authors)) {
authors = typeof authors === 'string' ? [{ name: authors }] : null;
} Defensive patterns
Strategy: type-guard
Validate before calling
function sanitizeAuthors(a) {
if (a == null) return null;
if (Array.isArray(a)) return a;
if (typeof a === 'string' && a.trim()) return [{ name: a.trim() }];
return null; // drop malformed shapes
} Type guard
function isAuthorList(v) {
return v == null || (Array.isArray(v) && v.every(x => x && typeof x === 'object' && typeof x.name === 'string'));
} Try / catch
try {
return normalizePaperRow(paper, 'citation');
} catch (err) {
if (/malformed authors/.test(err.message)) {
return normalizePaperRow({ ...paper, authors: null }, 'citation');
}
throw err;
} Prevention
- Normalize authors to an array of {name} objects at ingestion time.
- Validate fixtures against the expected row shape before use.
- Watch for S2 schema changes affecting the authors field.
When it happens
Trigger: The API (or an intermediary/proxy) returns authors as an object, string, or other non-array value on a paper row that normalizePaperRow is processing.
Common situations: Semantic Scholar schema drift changing the authors container; a proxy caching an older response shape; hand-written fixtures with authors: 'Smith, J.' instead of an array.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- semanticscholar ${label} row is not an object
- semanticscholar ${label} must be a number when present
- semanticscholar ${label} row is missing paperId
- semanticscholar ${label} row is missing title
- ${label} must be an integer between ${min} and ${max}, got $
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/bbc56ea2c33065c8.
Report an issue: GitHub.