jackwener/OpenCLI · error · CommandExecutionError

Pixiv bookmark item returned malformed ${label}

Error message

Pixiv bookmark item returned malformed ${label}

What it means

optionalCount validates optional numeric count fields (e.g. view/bookmark counts) on a Pixiv bookmark item. If a value is present but is not a non-negative safe integer, CommandExecutionError 'Pixiv bookmark item returned malformed <label>' is thrown with the field label.

Source

Thrown at clis/pixiv/bookmark-utils.js:46

export function tagsToString(tags) {
  if (tags == null) return '';
  const values = Array.isArray(tags) ? tags : (Array.isArray(tags?.tags) ? tags.tags : null);
  if (!values) {
    throw new CommandExecutionError('Pixiv item returned malformed tags payload');
  }
  return values.map((entry) => {
    const value = typeof entry === 'string' ? entry : entry?.tag;
    if (typeof value !== 'string' || !value.trim()) {
      throw new CommandExecutionError('Pixiv item returned malformed tag');
    }
    return value.trim();
  }).join(', ');
}

function optionalCount(value, label, fallback = '') {
  if (value == null || value === '') return fallback;
  if (!Number.isSafeInteger(value) || value < 0) {
    throw new CommandExecutionError(`Pixiv bookmark item returned malformed ${label}`);
  }
  return value;
}

export function normalizeBookmarkWorks(body) {
  if (Array.isArray(body)) return body;
  if (Array.isArray(body?.works)) return body.works;
  if (body?.works && typeof body.works === 'object') return Object.values(body.works);
  throw new CommandExecutionError('Pixiv bookmarks returned malformed payload');
}

export function bookmarkRow(work, index, type, bookmarkOwnerId) {
  const item = requirePixivPayloadObject(work, 'Pixiv bookmark item');
  const isNovel = type === 'novel';
  const id = requirePixivId(item.id ?? (isNovel ? item.novelId : item.illustId), 'Pixiv bookmark item');
  const title = requirePixivString(item.title ?? item.illustTitle, 'Pixiv bookmark item');
  const author = requirePixivString(item.userName ?? item.user_name, 'Pixiv bookmark item');
  const userId = requirePixivId(item.userId ?? item.user_id, 'Pixiv bookmark item');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Ensure the count field is a plain non-negative integer in the item JSON
  2. If using a proxy or scraper, convert counts to integers before passing the item to the row builders
  3. Check for API/lib version drift and update, or pre-parse string counts with parseInt

Example fix

// before
item.totalView = '1.2k'
// after
item.totalView = 1200
Defensive patterns

Strategy: validation

Validate before calling

function hasValidCounts(item) { return ['totalView','totalBookmarks'].every(k => item?.[k] == null || item[k] === '' || (Number.isSafeInteger(item[k]) && item[k] >= 0)); }
if (!hasValidCounts(item)) throw new Error('Bookmark item has malformed count fields');

Type guard

function isOptionalCount(v) { return v == null || v === '' || (Number.isSafeInteger(v) && v >= 0); }

Try / catch

try { const row = bookmarkRow(item); /* ... */ } catch (err) { if (err.message.startsWith('Pixiv bookmark item returned malformed')) { console.warn('Skipping item with malformed count:', item.id); return null; } throw err; }

Prevention

When it happens

Trigger: A bookmark item carrying a count as a formatted string ('1.2k'), a float, a negative number, or a number exceeding Number.MAX_SAFE_INTEGER from a non-standard endpoint.

Common situations: Proxy/mirror APIs that pre-format counts, scraped data instead of the official JSON, API changes making counts strings, mocks with placeholder values like 'N/A'.

Understand the failure class

Related errors


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