{"record":{"id":"9f652ff5c00f26b9","repo":"paperclipai/paperclip","slug":"this-command-requires-yes-when-not-running-in-an","errorCode":null,"errorMessage":"This command requires --yes when not running in an interactive terminal.","messagePattern":"This command requires --yes when not running in an interactive terminal\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/client/skills.ts","lineNumber":1013,"sourceCode":"async function readBodyFile(filePath: string): Promise<string> {\n  if (filePath === \"-\") {\n    return readStdin();\n  }\n  return readFile(filePath, \"utf8\");\n}\n\nasync function readStdin(): Promise<string> {\n  const chunks: Buffer[] = [];\n  for await (const chunk of process.stdin) {\n    chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n  }\n  return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nasync function confirmDangerousAction(yes: boolean | undefined, message: string): Promise<void> {\n  if (yes) return;\n  if (!process.stdin.isTTY || !process.stdout.isTTY) {\n    throw new Error(\"This command requires --yes when not running in an interactive terminal.\");\n  }\n  const rl = createInterface({ input, output });\n  try {\n    const answer = (await rl.question(`${message} Type yes to continue: `)).trim().toLowerCase();\n    if (answer !== \"yes\") {\n      throw new Error(\"Aborted.\");\n    }\n  } finally {\n    rl.close();\n  }\n}\n","sourceCodeStart":995,"sourceCodeEnd":1025,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/client/skills.ts#L995-L1025","documentation":"Thrown by confirmDangerousAction() when a destructive operation (skills reset/remove, skills agent clear) is invoked without --yes and either stdin or stdout is not a TTY. The function cannot prompt for confirmation in a non-interactive context, so it aborts rather than silently proceeding. This protects CI/agent runs from accidental destructive actions.","triggerScenarios":"Running `skills reset`, `skills remove`, or `skills agent clear` in CI, a pipe, a detached agent run, or any context where stdin/stdout is redirected — without passing --yes.","commonSituations":"Paperclip task/agent runs (PAPERCLIP_TASK_ID set), cron jobs, shell pipelines, Docker exec without a tty, or `nohup`/`&` invocations.","solutions":["Add --yes to pre-confirm the destructive action in non-interactive runs.","If you genuinely need the prompt, run inside an allocated PTY (e.g. `script -qec`).","For agent automation, set --yes explicitly rather than relying on TTY detection."],"exampleFix":"# before\npaperclipai skills remove my-skill\n# after\npaperclipai skills remove my-skill --yes","handlingStrategy":"validation","validationCode":"const isInteractive = Boolean(process.stdin.isTTY && process.stdout.isTTY);\nconst args = [\"skills\", \"remove\", ref];\nif (!isInteractive) args.push(\"--yes\");\nawait run(args);","typeGuard":"function isInteractiveTty(): boolean {\n  return Boolean(process.stdin.isTTY && process.stdout.isTTY);\n}","tryCatchPattern":null,"preventionTips":["Always pass --yes for destructive commands in CI/agent contexts.","Detect TTY up front and inject --yes automatically.","Never assume an interactive prompt in automated runs."],"tags":["cli","tty","interactive","confirmation","destructive"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}