{"record":{"id":"2355915327082478","repo":"stablyai/orca","slug":"could-not-generate-a-unique-name-for-originalna","errorCode":null,"errorMessage":"Could not generate a unique name for '${originalName}' after ${counter} attempts","messagePattern":"Could not generate a unique name for '(.+?)' after (.+?) attempts","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/filesystem-import-ssh.ts","lineNumber":249,"sourceCode":"    !reservedNames.has(candidate)\n  ) {\n    return candidate\n  }\n\n  let counter = 2\n  while (counter < 10000) {\n    candidate = `${stem} copy ${counter}${ext}`\n    assertCurrent?.()\n    if (\n      !(await remotePathExists(provider, `${destDir}/${candidate}`)) &&\n      !reservedNames.has(candidate)\n    ) {\n      return candidate\n    }\n    counter += 1\n  }\n\n  throw new Error(\n    `Could not generate a unique name for '${originalName}' after ${counter} attempts`\n  )\n}\n\nasync function ensureDropStagingDir(\n  provider: IFilesystemProvider,\n  destDir: string,\n  assertCurrent?: () => void\n): Promise<void> {\n  const parent = posix.dirname(destDir)\n  assertCurrent?.()\n  await provider.createDir(parent)\n  const gitignorePath = `${parent}/.gitignore`\n  assertCurrent?.()\n  if (!(await remotePathExists(provider, gitignorePath))) {\n    assertCurrent?.()\n    await provider.writeFile(gitignorePath, '*\\n!.gitignore\\n')\n  }","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/filesystem-import-ssh.ts#L231-L267","documentation":"Thrown by deconflictName() after exhausting its collision-avoidance loop. It first tries the original name, then 'stem copy.ext', then 'stem copy 2.ext' … up to counter < 10000 (candidates 'stem copy 2' through 'stem copy 9999'). Each candidate is checked via remotePathExists (provider.stat) and the in-process reservedNames set. If none of ~9998 numbered candidates is free, the directory is treated as saturated and the import of that source fails.","triggerScenarios":"Importing a source whose originalName collides in destDir, and the destination already contains 'name copy.ext' plus 'name copy 2'…'name copy 9999' (or reservedNames in the current batch blocks them all). provider.stat reports every numbered candidate as existing.","commonSituations":"Importing into a destination that has accumulated thousands of copies of the same name (logically unbounded duplicate generation); a batch import where reservedNames from earlier items collide with all generated candidates; an adversarial or auto-generated remote directory filled to brute-force the deconflict loop.","solutions":["Choose a different destination directory for the import.","Clean up the accumulated 'name copy N' entries in the destination before retrying.","Rename the source before importing so its basename is unique in the destination.","Reduce the batch size so reservedNames cannot exhaust the candidate space."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before importing, sanity-check the destination is not saturated with copies\nimport { readdir } from 'node:fs/promises'\nasync function copySaturation(dir: string, stem: string): Promise<number> {\n  try {\n    const names = await readdir(dir)\n    return names.filter(n => n.startsWith(stem + ' copy')).length\n  } catch { return 0 }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await importExternalPathsSsh([src], dest, connId, opts)\n} catch (e) {\n  if (e instanceof Error && /Could not generate a unique name/.test(e.message)) {\n    // route to a different dest dir, or rename src, then retry\n  } else throw e\n}","preventionTips":["Pick a destination directory that does not already hold thousands of 'name copy N' entries.","Rename the source so its basename is unique before importing.","Keep batch import sizes modest so reservedNames cannot exhaust the candidate space."],"tags":["ssh","upload","name-collision","deconflict"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}