jackwener/OpenCLI · error · CommandExecutionError
semanticscholar ${label} row is missing title
Error message
semanticscholar ${label} row is missing title What it means
normalizePaperRow requires a non-empty string `title` on each paper row; the adapter's table output depends on it. Rows whose title is missing, empty, or whitespace-only throw this CommandExecutionError. Like the paperId check, this guards the adapter's display contract.
Source
Thrown at clis/semanticscholar/utils.js:170
}
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 = {
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;
}View on GitHub (pinned to 49907e53dc)
Solutions
- Include `title` in the `fields` query parameter of the API request.
- Filter or substitute rows lacking titles before normalizePaperRow.
- Fall back to a placeholder title ('(untitled)') for incomplete records if acceptable.
- Retry with a different identifier (DOI/arXiv) that resolves to a fully indexed record.
Example fix
// before
fetch(`${S2_GRAPH_BASE}/paper/${ref}?fields=paperId`)
// after
fetch(`${S2_GRAPH_BASE}/paper/${ref}?fields=paperId,title,authors,year,citationCount`) Defensive patterns
Strategy: validation
Validate before calling
const url = `${S2_GRAPH_BASE}/paper/${ref}?fields=paperId,title,authors,year,citationCount`;
const titled = rows.filter(r => typeof r?.title === 'string' && r.title.trim()); Type guard
function hasTitle(v) {
return v !== null && typeof v === 'object' && typeof v.title === 'string' && v.title.trim().length > 0;
} Try / catch
try {
return normalizePaperRow(paper, 'citation');
} catch (err) {
if (/missing title/.test(err.message)) {
return normalizePaperRow({ ...paper, title: '(untitled)' }, 'citation');
}
throw err;
} Prevention
- Include title in the `fields` query parameter of every paper request.
- Substitute a placeholder for untitled records if display requires it.
- Prefer well-indexed records (DOI/arXiv refs) over obscure ids.
When it happens
Trigger: A paper record from citations/references/recommendations has no title — e.g. S2 only has a bare identifier for that record, or `title` was omitted from the `fields` param in the request URL.
Common situations: Very obscure or non-English records without indexed titles; requests built with a minimal fields list (e.g. `?fields=paperId`) that drop title; dataset dumps with placeholder rows.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- semanticscholar ${label} row is missing paperId
- semanticscholar ${label} row is not an object
- semanticscholar ${label} row has malformed authors
- ${label} did not include a stable ${field}.
- Bilibili comments reply ${index + 1} was malformed
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/60d801d80785c29d.
Report an issue: GitHub.