paperclipai/paperclip · error · Error

`pi --list-models` failed: ${detail}

Error message

`pi --list-models` failed: ${detail}

What it means

Thrown by discoverPiModels when `pi --list-models` exits non-zero. The detail is the first non-empty line of stderr then stdout, surfacing pi's own error message.

Source

Thrown at packages/adapters/pi-local/src/server/models.ts:131

  const result = await runChildProcess(
    `pi-models-${Date.now()}-${Math.random().toString(16).slice(2)}`,
    command,
    ["--list-models"],
    {
      cwd,
      env: runtimeEnv,
      timeoutSec: 20,
      graceSec: 3,
      onLog: async () => {},
    },
  );

  if (result.timedOut) {
    throw new Error("`pi --list-models` timed out.");
  }
  if ((result.exitCode ?? 1) !== 0) {
    const detail = firstNonEmptyLine(result.stderr) || firstNonEmptyLine(result.stdout);
    throw new Error(detail ? `\`pi --list-models\` failed: ${detail}` : "`pi --list-models` failed.");
  }

  // Pi outputs model list to stderr, but fall back to stdout for older versions
  const output = result.stderr || result.stdout;
  return sortModels(dedupeModels(parseModelsOutput(output)));
}

function normalizeEnv(input: unknown): Record<string, string> {
  const envInput = typeof input === "object" && input !== null && !Array.isArray(input)
    ? (input as Record<string, unknown>)
    : {};
  const env: Record<string, string> = {};
  for (const [key, value] of Object.entries(envInput)) {
    if (typeof value === "string") env[key] = value;
  }
  return env;
}

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Read the detail line for pi's own diagnostic.
  2. Install pi and ensure it is on PATH (or override the command).
  3. Authenticate the pi provider (API key env or pi login).
  4. Run `pi --list-models` in the same env to reproduce and fix.
Defensive patterns

Strategy: try-catch

Validate before calling

async function piInstalled(): Promise<boolean> {
  try { await runChildProcess("probe", "pi", ["--version"], { timeoutSec: 5, graceSec: 1, onLog: async () => {} }); return true; } catch { return false; }
}

Try / catch

try {
  return await discoverPiModels(input);
} catch (e) {
  if (e instanceof Error && /`pi --list-models` failed/.test(e.message)) {
    // read detail; install/auth pi; non-retryable until fixed
  }
  throw e;
}

Prevention

When it happens

Trigger: runChildProcess returns exitCode != 0 (not timedOut) for `pi --list-models`; detail = firstNonEmptyLine(stderr) || firstNonEmptyLine(stdout).

Common situations: pi not installed or not on PATH; provider auth missing/expired; corrupt pi config; incompatible pi version.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/8985dc7f39e5e6a4. Report an issue: GitHub.