jackwener/OpenCLI · error · CommandExecutionError
Pixiv user profile returned malformed novels payload
Error message
Pixiv user profile returned malformed novels payload
What it means
requireProfileNovelIds validates the Pixiv user profile response's novels field: it must be a non-null, non-array object (a map of novelId -> data). If novels is missing/null, is an array, or is a non-object primitive, the library throws because the profile payload shape is unusable for enumerating novel IDs. This guards against Pixiv schema changes or error responses being parsed as a valid profile.
Source
Thrown at clis/pixiv/novels.js:44
}
const title = requirePixivString(item.title, 'Pixiv user novel item');
return {
rank,
title,
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({View on GitHub (pinned to 49907e53dc)
Solutions
- Log the full response body/status to see what actually came back (auth failure vs shape change)
- Handle the empty case before parsing: if the user has no novels, treat empty array/missing as zero results rather than an error
- Verify the target user ID is valid, public, and not deleted
- Check for rate-limit/login requirements (Pixiv may need cookies/PHPSESSID) and retry with valid auth
- Update the parser to accept both object-map and array forms of novels
Example fix
// before
const ids = requireProfileNovelIds(body);
// after
if (body && Array.isArray(body.novels)) {
body.novels = Object.fromEntries(body.novels.map(n => [String(n.id), n]));
}
const ids = requireProfileNovelIds(body); Defensive patterns
Strategy: validation
Validate before calling
function hasValidNovelsMap(body) {
return body != null &&
typeof body.novels === 'object' && body.novels !== null &&
!Array.isArray(body.novels);
}
if (!hasValidNovelsMap(body)) throw new Error('Profile response unusable: novels is not an object map'); Type guard
function hasNovelsMap(p) {
return typeof p === 'object' && p !== null &&
typeof p.novels === 'object' && p.novels !== null && !Array.isArray(p.novels);
}
// usage: if (hasNovelsMap(profile)) { Object.keys(profile.novels) ... } Try / catch
try {
const ids = requireProfileNovelIds(body);
} catch (err) {
if (String(err.message).includes('malformed novels payload')) {
console.warn('No usable novels map (empty account, private user, or auth/rate-limit body); returning []');
return [];
}
throw err;
} Prevention
- Check HTTP status and auth state before parsing profile JSON
- Treat 'user has no novels' as an empty result, not an error
- Record Pixiv API fixtures and test the parser against them to catch schema changes
- Validate the user ID exists and is public before querying
When it happens
Trigger: Pixiv profile endpoint returns {novels: null}, {novels: []}, {novels: '123'}, or omits novels entirely — often when the user has no novels, the user does not exist/is private, or the API returns an error/HTML page parsed loosely.
Common situations: Querying a user ID that has zero novels (API may return empty array instead of object); deleted or restricted accounts; rate-limit or auth-failure bodies being fed to the parser; Pixiv API version drift changing novels from map to list.
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
- Pixiv user novel details returned malformed works payload
- Pixiv user novel item returned malformed ${label}
- Pixiv user novels returned mismatched novel detail payload f
- Manus skills returned a malformed API payload
- Refusing to write local Pixiv downloads: pass --execute
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/78b0d1b2c035d45f.
Report an issue: GitHub.