jackwener/OpenCLI · info · ArgumentError

Refusing to write a local Pixiv novel: pass --execute

Error message

Refusing to write a local Pixiv novel: pass --execute

What it means

The pixiv novel-download command writes a local file on disk, which is a destructive/side-effectful action. To prevent accidental writes (e.g. when previewing results or scripting), the command requires an explicit --execute flag. If kwargs.execute is not exactly true, the command throws ArgumentError and writes nothing.

Source

Thrown at clis/pixiv/novel-download.js:21

import { fetchNovelForDownload, normalizeNovelFileFormat, normalizePixivOutputRoot, writeNovelFile } from './novel-download-utils.js';

cli({
  site: 'pixiv',
  name: 'novel-download',
  access: 'read',
  description: 'Download Pixiv novel text as txt or markdown',
  domain: 'www.pixiv.net',
  strategy: Strategy.COOKIE,
  args: [
    { name: 'novel-id', positional: true, required: true, help: 'Novel ID' },
    { name: 'output', default: './pixiv-downloads/novels', help: 'Output directory' },
    { name: 'file-format', default: 'txt', help: 'Output file format: txt or md' },
    { name: 'execute', type: 'boolean', default: false, help: 'Actually write the local novel file' },
  ],
  columns: ['novel_id', 'title', 'format', 'status', 'path'],
  func: async (page, kwargs) => {
    if (kwargs.execute !== true) {
      throw new ArgumentError('Refusing to write a local Pixiv novel: pass --execute');
    }
    const id = String(kwargs['novel-id'] ?? '');
    if (!/^\d+$/.test(id)) {
      throw new ArgumentError(`Invalid novel ID: ${id}`, 'Example: opencli pixiv novel-download 10588915 --file-format txt');
    }
    const format = normalizeNovelFileFormat(kwargs['file-format'] ?? kwargs.format);
    const output = normalizePixivOutputRoot(kwargs.output, './pixiv-downloads/novels');
    const body = await fetchNovelForDownload(page, id);
    const destPath = writeNovelFile(body, output, format);
    return [{ novel_id: body.id, title: body.title, format, status: 'success', path: destPath }];
  },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the command with the --execute flag: `opencli pixiv novel-download 10588915 --execute --file-format txt`.
  2. Ensure the flag is parsed as a boolean true — the guard is strict (`!== true`), so quoted or string values like --execute=false or "true" will still throw.
  3. If intentionally doing a dry run, this error is expected; treat it as the safety gate and add --execute only when ready to write.

Example fix

// before
opencli pixiv novel-download 10588915 --file-format txt
// after
opencli pixiv novel-download 10588915 --file-format txt --execute
Defensive patterns

Strategy: validation

Validate before calling

// validate args before invoking the command
function canRunNovelDownload(args) {
  return args.execute === true && /^\d+$/.test(String(args['novel-id'] ?? ''));
}
if (!canRunNovelDownload(args)) {
  console.error('Pass --execute and a numeric --novel-id, e.g. opencli pixiv novel-download 10588915 --execute --file-format txt');
  process.exit(1);
}

Type guard

function hasExecuteFlag(args) {
  return typeof args === 'object' && args !== null && args.execute === true;
}

Prevention

When it happens

Trigger: Running `opencli pixiv novel-download <id> ...` without the --execute flag, or passing --execute with a truthy non-boolean value that doesn't strictly equal true (the check is `kwargs.execute !== true`).

Common situations: Developers running the command for the first time expecting it to download by default; scripts/CI pipelines that omit --execute; copy-pasted commands from docs that show the dry-run form.

Related errors


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