abhigyanpatwari/GitNexus · error · BadRequestError
Could not allocate an upload directory after ${MAX_NAME_COLL
Error message
Could not allocate an upload directory after ${MAX_NAME_COLLISION_TRIES} attempts What it means
pickAvailableName in analyze-upload.ts tries the sanitized upload name and then -2, -3, ... suffixes under UPLOAD_ROOT, up to MAX_NAME_COLLISION_TRIES=100 attempts; if every candidate directory already exists (or getUploadDir rejects the name), it throws BadRequestError 409. It exists to bound the collision scan instead of looping forever.
Source
Thrown at gitnexus/src/server/analyze-upload.ts:61
* collision with an existing upload. Bounded to avoid an unbounded scan.
*/
async function pickAvailableName(base: string): Promise<string> {
for (let i = 0; i < MAX_NAME_COLLISION_TRIES; i++) {
const name = i === 0 ? base : `${base}-${i + 1}`;
let dir: string;
try {
dir = getUploadDir(name);
} catch {
continue;
}
try {
await fsp.access(dir);
// exists → try the next suffix
} catch {
return name; // ENOENT → available
}
}
throw new BadRequestError(
`Could not allocate an upload directory after ${MAX_NAME_COLLISION_TRIES} attempts`,
409,
);
}
export function createAnalyzeUploadHandler(deps: AnalyzeUploadDeps) {
const ingest = deps.ingest ?? ingestUpload;
return async function handleAnalyzeUploadRequest(req: Request, res: Response): Promise<void> {
let stageRoot: string | undefined;
let promotedDir: string | undefined;
let createdJobId: string | undefined;
let launched = false;
try {
const result = await ingest(req as IncomingMessage);
stageRoot = result.stageRoot;
const baseName = deriveUploadName(result.topLevelName);View on GitHub (pinned to aac7515d2a)
Solutions
- Delete or archive old upload directories under the upload root (inside the server's GITNEXUS_HOME data volume) and retry
- Rename the top-level folder before uploading so the derived base name differs
- Add periodic cleanup that removes upload dirs whose analysis jobs are terminal
Example fix
# before: 101 uploads of 'my-project' exist rm -rf "$GITNEXUS_HOME"/uploads/my-project* # or archive them; then re-upload # after: unique name avoids the collision entirely mv my-project my-project-run-42 && upload again
Defensive patterns
Strategy: retry
Validate before calling
// client-side: make collisions unlikely before uploading
const uniqueFolderName = `${baseFolderName}-${Date.now().toString(36)}`;
formData.set('name', uniqueFolderName); Type guard
function willNotCollide(base, existingNames) {
const candidates = [base, ...Array.from({ length: 100 }, (_, i) => `${base}-${i + 2}`)];
return candidates.some((c) => !existingNames.includes(c));
} Try / catch
// server operator: free suffix space, then the caller retries
try { await postUpload(formData); }
catch (e) {
if (/Could not allocate an upload directory/.test(String(e.message))) {
await cleanupTerminalUploadDirs(); // rm/archive finished upload dirs under GITNEXUS_HOME uploads
return postUpload(formData);
}
throw e;
} Prevention
- Suffix the uploaded folder name with a run id (timestamp/CI build number)
- Schedule cleanup of upload directories whose jobs are terminal
- Alert when the count of same-base upload dirs approaches 100
When it happens
Trigger: POST /api/analyze/upload of a folder whose derived name already has 100 suffixed siblings (base, base-2 ... base-101 all present); typically after ~100 uploads of the same-named folder with no cleanup of old upload directories.
Common situations: CI pipelines or classroom/demo setups repeatedly uploading the identically-named folder; an operator never pruning UPLOAD_ROOT under the server's data dir (GITNEXUS_HOME); long-lived self-hosted instances.
Related errors
- Analysis already in progress (job ${job.id})
- Too many directories in upload
- No suitable device found
- Analysis already in progress (job ${job.id})
- Uploaded folder has no usable name
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/9d7a625723f48dd7.
Report an issue: GitHub.