{"record":{"id":"76e787ed61510d37","repo":"paperclipai/paperclip","slug":"export-cancelled","errorCode":null,"errorMessage":"Export cancelled.","messagePattern":"Export cancelled\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"info","filePath":"cli/src/commands/client/company.ts","lineNumber":1264,"sourceCode":"  const entries = await readdir(root);\n  if (entries.length === 0) return;\n\n  // --force skips the guard for non-interactive/automated callers (e.g. the\n  // nightly backup routine, which exports into a git clone that legitimately\n  // still holds .git and BACKUP-README.md after cleaning tracked content).\n  if (opts.force) return;\n\n  if (!process.stdin.isTTY || !process.stdout.isTTY) {\n    throw new Error(`Export output directory ${root} already contains files. Re-run interactively, pass --force, or choose an empty directory.`);\n  }\n\n  const confirmed = await p.confirm({\n    message: `Overwrite existing files in ${root}?`,\n    initialValue: false,\n  });\n\n  if (p.isCancel(confirmed) || !confirmed) {\n    throw new Error(\"Export cancelled.\");\n  }\n}\n\nfunction matchesPrefix(company: Company, selector: string): boolean {\n  return company.issuePrefix.toUpperCase() === selector.toUpperCase();\n}\n\nexport function resolveCompanyForDeletion(\n  companies: Company[],\n  selectorRaw: string,\n  by: CompanyDeleteSelectorMode = \"auto\",\n): Company {\n  const selector = normalizeSelector(selectorRaw);\n  if (!selector) {\n    throw new Error(\"Company selector is required.\");\n  }\n\n  const idMatch = companies.find((company) => company.id === selector);","sourceCodeStart":1246,"sourceCodeEnd":1282,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/client/company.ts#L1246-L1282","documentation":"Thrown by confirmOverwriteExportDirectory when the user was shown the 'Overwrite existing files?' prompt and either cancelled (ESC/Ctrl-C via p.isCancel) or answered 'no'. This is a deliberate user-initiated abort, not a system error.","triggerScenarios":"Interactive export into a non-empty directory where the operator declines the overwrite confirmation, or presses escape/ctrl-c at the @clack/prompts confirm.","commonSituations":"An operator realizes mid-export that the directory contains important files and bails out. A user fat-fingers 'no' on the prompt. Piping interrupted input that registers as a cancel.","solutions":["Re-run the export and answer 'yes' at the prompt if overwriting is acceptable.","Choose a different --out directory and re-run.","Move or delete the existing files first, then re-run.","Use --force to skip the prompt for trusted automated overwrites."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await confirmOverwriteExportDirectory(outDir);\n} catch (err) {\n  if (err instanceof Error && /Export cancelled/.test(err.message)) {\n    // user-initiated abort; exit cleanly\n    process.exit(0);\n  }\n  throw err;\n}","preventionTips":["Pre-check the target directory and pre-clean it when overwriting is intended.","Use --force in trusted automated contexts to skip the prompt.","Treat a cancel as expected control flow, not an error, in wrappers."],"tags":["cli","user-cancel","company-export","interactive"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}