{"record":{"id":"f1934b6f91854f3a","repo":"paperclipai/paperclip","slug":"output-path-already-exists-and-is-not-a-directory","errorCode":null,"errorMessage":"Output path already exists and is not a directory: ${outputDir}","messagePattern":"Output path already exists and is not a directory: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/client/feedback.ts","lineNumber":559,"sourceCode":"\nfunction horizontalRule(): string {\n  return pc.dim(\"-\".repeat(72));\n}\n\nfunction padRight(value: string, width: number): string {\n  return `${value}${\" \".repeat(Math.max(0, width - value.length))}`;\n}\n\nfunction defaultFeedbackExportDirName(): string {\n  const iso = new Date().toISOString().replace(/[-:]/g, \"\").replace(/\\.\\d{3}Z$/, \"Z\");\n  return `feedback-export-${iso}`;\n}\n\nasync function ensureEmptyOutputDirectory(outputDir: string): Promise<void> {\n  try {\n    const info = await stat(outputDir);\n    if (!info.isDirectory()) {\n      throw new Error(`Output path already exists and is not a directory: ${outputDir}`);\n    }\n    const entries = await readdir(outputDir);\n    if (entries.length > 0) {\n      throw new Error(`Output directory already exists and is not empty: ${outputDir}`);\n    }\n  } catch (error) {\n    const message = error instanceof Error ? error.message : \"\";\n    if (/ENOENT/.test(message)) {\n      await mkdir(outputDir, { recursive: true });\n      return;\n    }\n    throw error;\n  }\n}\n\nasync function collectJsonFilesForArchive(\n  outputDir: string,\n  relativePaths: string[],","sourceCodeStart":541,"sourceCodeEnd":577,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/client/feedback.ts#L541-L577","documentation":"ensureEmptyOutputDirectory stats the target path; if it exists and is not a directory (i.e., a file or symlink to a file), it refuses to proceed to avoid clobbering.","triggerScenarios":"Passing --output <path> where <path> is an existing regular file.","commonSituations":"Reusing a name that a previous run or another tool created as a file; --output pointing at an archive file.","solutions":["Remove or rename the existing file at that path.","Point --output at a fresh directory path.","Omit --output to let the CLI generate a timestamped feedback-export-<iso> directory."],"exampleFix":"// before\npaperclipai feedback trace export --output ./out.zip\n// after\nrm ./out.zip && paperclipai feedback trace export --output ./out.zip","handlingStrategy":"validation","validationCode":"import {stat} from 'node:fs/promises';\ntry {\n  const info = await stat(outputDir);\n  if (!info.isDirectory()) throw new Error(`Output path already exists and is not a directory: ${outputDir}`);\n} catch (e) { /* ENOENT is fine */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Let the CLI generate a timestamped default directory.","Pre-flight check --output paths in scripts."],"tags":["cli","feedback","filesystem","io"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}