{"record":{"id":"caffdbfb8e488a2a","repo":"firecrawl/pdf-inspector","slug":"could-not-allocate-a-unique-model-install-file","errorCode":null,"errorMessage":"could not allocate a unique model install file","messagePattern":"could not allocate a unique model install file","errorType":"error_code","errorClass":"ModelStoreError::Io","httpStatus":null,"severity":"error","filePath":"src/vision/models.rs","lineNumber":570,"sourceCode":"            .duration_since(UNIX_EPOCH)\n            .unwrap_or_default()\n            .as_nanos();\n        let path = root.join(format!(\n            \".{filename}.{}.{}.{}.part\",\n            std::process::id(),\n            timestamp,\n            sequence\n        ));\n        match OpenOptions::new().create_new(true).write(true).open(&path) {\n            Ok(file) => return Ok((path, file)),\n            Err(source) if source.kind() == io::ErrorKind::AlreadyExists => continue,\n            Err(source) => return Err(ModelStoreError::Io { path, source }),\n        }\n    }\n    let path = root.join(format!(\".{filename}.part\"));\n    Err(ModelStoreError::Io {\n        path,\n        source: io::Error::new(\n            io::ErrorKind::AlreadyExists,\n            \"could not allocate a unique model install file\",\n        ),\n    })\n}\n\n#[cfg(not(windows))]\nfn replace_file_atomic(source: &Path, target: &Path) -> io::Result<()> {\n    fs::rename(source, target)\n}\n\n#[cfg(windows)]\nfn replace_file_atomic(source: &Path, target: &Path) -> io::Result<()> {\n    use std::os::windows::ffi::OsStrExt;\n    use windows_sys::Win32::Storage::FileSystem::{\n        MoveFileExW, MOVEFILE_REPLACE_EXISTING, MOVEFILE_WRITE_THROUGH,\n    };\n","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/firecrawl/pdf-inspector/blob/636ca1a58bdc1af4cd3fc20b8c1f549a1121cca7/src/vision/models.rs#L552-L588","documentation":"create_temporary_file in src/vision/models.rs tries 16 times to create a unique '.{filename}.{pid}.{timestamp}.{seq}.part' file with create_new(true); if all 16 attempts collide with an existing file it returns ModelStoreError::Io with ErrorKind::AlreadyExists and message 'could not allocate a unique model install file'. This protects model installs: partial downloads are written to a .part file and atomically renamed, and this failure means the store could not reserve a scratch file.","triggerScenarios":"Downloading/installing a vision model into the model store when 16 consecutive create_new attempts all hit AlreadyExists — i.e. extreme filename collisions in the model root directory.","commonSituations":"A directory whose clock/timestamp resolution produces identical names (rare); a filesystem with broken create_new semantics (some network mounts, old NFS); leftover .part debris plus a frozen or wrapped counter; running many processes in lockstep on the same model root.","solutions":["Clear stale '.{filename}.*.part' files from the model root directory (the store's sweep_stale_install_files normally does this) and retry the install.","Point the model store root at a local filesystem (not NFS/network mount) where O_EXCL create_new works reliably.","Check filesystem permissions and free space on the model root; a persistent EACCES/ENOSPC surfaces as ModelStoreError::Io too.","If it recurs, report it — 16 collisions of pid+nanotimestamp+counter indicates a platform filesystem bug."],"exampleFix":"# before (model root on NFS)\nMODEL_STORE_ROOT=/mnt/nfs/models\n# after\nMODEL_STORE_ROOT=~/.cache/pdf-inspector/models","handlingStrategy":"retry","validationCode":"// before model install: ensure root is a local, writable dir without stale part files\nconst fs = require('fs');\nfunction prepareModelRoot(root) {\n  fs.mkdirSync(root, { recursive: true });\n  for (const f of fs.readdirSync(root)) {\n    if (f.startsWith('.') && f.endsWith('.part')) fs.rmSync(`${root}/${f}`, { force: true });\n  }\n}","typeGuard":"function isTempAllocFailure(e) {\n  return e instanceof Error && e.message.includes('could not allocate a unique model install file');\n}","tryCatchPattern":"try {\n  await store.ensureModel(name);\n} catch (e) {\n  if (isTempAllocFailure(e)) {\n    cleanPartFiles(modelRoot);\n    await store.ensureModel(name); // one retry after cleanup\n  } else throw e;\n}","preventionTips":["Keep the model store root on a local filesystem, not NFS/SMB, so create_new (O_EXCL) semantics work.","Periodically clean leftover .part files from crashed installs.","Ensure the process has write permission and free space in the model root.","Avoid running many install processes simultaneously against the same root."],"tags":["filesystem","io","model-store","temp-file"],"backgroundTag":"temp-file-already-exists","analyzedSha":"636ca1a58bdc1af4cd3fc20b8c1f549a1121cca7","analyzedAt":"2026-09-05T08:40:31.256Z","contentChangedAt":"2026-09-05T08:40:31.256Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}