jackwener/OpenCLI · error · CommandExecutionError
Pixiv novel ${id} returned malformed detail payload
Error message
Pixiv novel ${id} returned malformed detail payload What it means
requireNovelBody performs a structural pre-check on the Pixiv novel detail payload: body must be a non-null, non-array object. If it is null, an array, or a primitive, the library cannot extract the novel identity and throws CommandExecutionError naming the requested novel ID. This catches pages that failed to load or API calls that returned an unexpected top-level type.
Source
Thrown at clis/pixiv/novel.js:16
import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, CommandExecutionError } from '@jackwener/opencli/errors';
import { pixivFetch } from './utils.js';
import { dateOnly, tagsToString } from './bookmark-utils.js';
function optionalCount(value, label) {
if (value == null || value === '') return '';
if (!Number.isSafeInteger(value) || value < 0) {
throw new CommandExecutionError(`Pixiv novel returned malformed ${label}`);
}
return value;
}
function requireNovelBody(body, id) {
if (!body || Array.isArray(body) || typeof body !== 'object') {
throw new CommandExecutionError(`Pixiv novel ${id} returned malformed detail payload`);
}
const novelId = String(body.id ?? '').trim();
const title = String(body.title ?? '').trim();
const userName = String(body.userName ?? '').trim();
const userId = String(body.userId ?? '').trim();
if (!/^\d+$/.test(novelId) || novelId !== id || !title || !userName || !/^\d+$/.test(userId)) {
throw new CommandExecutionError(`Pixiv novel ${id} returned malformed detail payload`);
}
return { payload: body, identity: { novelId, title, userName, userId } };
}
export function novelRowFromBody(body, id) {
const normalized = requireNovelBody(body, id);
const b = normalized.payload;
const identity = normalized.identity;
if (b.seriesNavData != null && (Array.isArray(b.seriesNavData) || typeof b.seriesNavData !== 'object')) {
throw new CommandExecutionError('Pixiv novel returned malformed series metadata');
}View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the novel ID exists by opening it on pixiv.net; retry with a valid, non-deleted novel ID.
- Ensure you are authenticated (valid Pixiv session/cookies) — unauthenticated scrapes often return login pages instead of JSON.
- Retry later if rate-limited (Pixiv throttling commonly returns non-data responses).
- Update the library in case Pixiv changed its page structure and the scraper needs a fix.
Defensive patterns
Strategy: type-guard
Validate before calling
function looksLikeNovelBody(v) {
return v !== null && !Array.isArray(v) && typeof v === 'object';
}
if (!looksLikeNovelBody(body)) throw new Error('fetch failed — got non-object payload (login/error page?)'); Type guard
function isNovelDetailBody(v) {
return (
v !== null &&
!Array.isArray(v) &&
typeof v === 'object' &&
/^\d+$/.test(String(v.id ?? '')) &&
typeof v.title === 'string' && v.title.length > 0 &&
/^\d+$/.test(String(v.userId ?? ''))
);
} Try / catch
try {
const detail = await cli.pixiv.novelView({ id });
} catch (e) {
if (/malformed detail payload/.test(e.message)) {
console.error(`Novel ${id} payload invalid — check the ID exists, you are logged in, and the novel is public.`);
} else throw e;
} Prevention
- Verify the novel ID resolves on pixiv.net before scripting against it.
- Maintain valid Pixiv cookies/login; R-18 or login-walled content returns error pages.
- Back off and retry on rate limits before concluding the payload is malformed.
When it happens
Trigger: fetchNovelForDownload / novel detail fetch via pixivFetch returns null, an array, or a non-object (e.g. a parsed HTML string or error document) for the given novel id.
Common situations: Novel deleted or ID wrong so Pixiv returns a not-found/error page; not logged in / age-restricted or R-18 content blocked so the scraper receives a login page; rate-limiting returning an error body; network proxy mangling the response.
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
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/6b30b9901315c0b4.
Report an issue: GitHub.