jackwener/OpenCLI · error · CommandExecutionError
Pixiv user profile returned malformed novel ID: ${invalid}
Error message
Pixiv user profile returned malformed novel ID: ${invalid} What it means
After requireProfileNovelIds obtains the novels map, every key must be a numeric string (Pixiv novel ID). If any key fails /^\d+$/, the library throws naming the invalid key, because non-numeric keys (e.g. 'meta', 'next', or error fields embedded in the map) cannot be novel IDs and would produce broken detail requests downstream.
Source
Thrown at clis/pixiv/novels.js:49
novel_id: id,
words: optionalCount(item.wordCount, 'word count'),
characters: optionalCount(item.textCount ?? item.characterCount, 'character count'),
bookmarks: optionalCount(item.bookmarkCount, 'bookmark count', 0),
tags: tagsToString(item.tags),
created: dateOnly(item.createDate),
url: `https://www.pixiv.net/novel/show.php?id=${id}`,
};
}
function requireProfileNovelIds(body) {
const payload = requirePixivPayloadObject(body, 'Pixiv user profile');
if (!payload.novels || Array.isArray(payload.novels) || typeof payload.novels !== 'object') {
throw new CommandExecutionError('Pixiv user profile returned malformed novels payload');
}
const ids = Object.keys(payload.novels);
const invalid = ids.find(id => !/^\d+$/.test(id));
if (invalid) {
throw new CommandExecutionError(`Pixiv user profile returned malformed novel ID: ${invalid}`);
}
return ids;
}
function requireDetailWorks(body) {
const payload = requirePixivPayloadObject(body, 'Pixiv user novel details');
if (!payload.works || Array.isArray(payload.works) || typeof payload.works !== 'object') {
throw new CommandExecutionError('Pixiv user novel details returned malformed works payload');
}
return payload.works;
}
cli({
site: 'pixiv',
name: 'novels',
access: 'read',
description: "List a Pixiv user's novels",
domain: 'www.pixiv.net',View on GitHub (pinned to 49907e53dc)
Solutions
- Log Object.keys(payload.novels) and inspect which key is non-numeric
- Filter out known non-numeric/metadata keys before passing the payload to the CLI
- Normalize keys by stripping non-digit prefixes (e.g. key.replace(/^\D+/, '')) if the API changed key format
- Refresh fixtures/cache with a fresh API response reflecting the current schema
Example fix
// before
const ids = requireProfileNovelIds(body);
// after
const cleaned = { ...body, novels: Object.fromEntries(
Object.entries(body.novels).filter(([k]) => /^\d+$/.test(k))
)};
const ids = requireProfileNovelIds(cleaned); Defensive patterns
Strategy: validation
Validate before calling
const ids = Object.keys(body?.novels ?? {});
const invalid = ids.filter(id => !/^\d+$/.test(id));
if (invalid.length) {
console.warn('Ignoring non-numeric novel keys:', invalid);
}
const validIds = ids.filter(id => /^\d+$/.test(id)); Type guard
function isNumericIdKey(k) {
return /^\d+$/.test(k);
}
function numericIdKeys(novels) {
return Object.keys(novels).filter(isNumericIdKey);
} Try / catch
try {
ids = requireProfileNovelIds(body);
} catch (err) {
const m = String(err.message).match(/malformed novel ID: (.+)$/);
if (m) {
console.warn(`Filtering out invalid novel key "${m[1]}"`);
ids = Object.keys(body.novels).filter(k => /^\d+$/.test(k));
} else throw err;
} Prevention
- Filter object keys against /^\d+$/ before consuming API maps
- Normalize key formats (strip prefixes like 'novel_') if the API changes them
- Keep fixtures current so metadata keys added by Pixiv are caught in tests
- Log rejected keys instead of silently discarding them
When it happens
Trigger: The profile novels object contains non-ID keys — e.g. the API nests pagination/metadata fields alongside numeric IDs, keys arrive with quotes/whitespace/prefixes ('novel_123'), or a mocked/local fixture uses string slugs instead of numeric IDs.
Common situations: Pixiv API schema drift adding metadata keys to the novels map; hand-crafted test fixtures or cached snapshots with slug keys; a proxy rewriting keys; copying payload from docs with placeholder keys.
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
- Invalid bookmark type: ${type}. Expected "illust" or "novel"
- Pixiv user novel item returned malformed ${label}
- ${label} is required
- ${label} must be a positive integer
- ${label} must be <= ${maxValue}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0336e3b90243ddd0.
Report an issue: GitHub.