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

  1. Verify the novel ID exists by opening it on pixiv.net; retry with a valid, non-deleted novel ID.
  2. Ensure you are authenticated (valid Pixiv session/cookies) — unauthenticated scrapes often return login pages instead of JSON.
  3. Retry later if rate-limited (Pixiv throttling commonly returns non-data responses).
  4. 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

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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/6b30b9901315c0b4. Report an issue: GitHub.