{"record":{"id":"2892c058dad242c5","repo":"shadcn-ui/ui","slug":"could-not-back-up-filepath-2892c0","errorCode":null,"errorMessage":"Could not back up ${filePath}.","messagePattern":"Could not back up (.+?)\\.","errorType":"exception","errorClass":"FileBackupError","httpStatus":null,"severity":"error","filePath":"packages/shadcn/src/utils/file-helper.ts","lineNumber":74,"sourceCode":"    return true\n  } catch {\n    // Best effort - don't log as this is just cleanup\n    return false\n  }\n}\n\nexport async function withFileBackup<T>(\n  filePath: string,\n  task: () => Promise<T>\n) {\n  if (!fsExtra.existsSync(filePath)) {\n    return task()\n  }\n\n  const backupPath = createFileBackup(filePath)\n\n  if (!backupPath) {\n    throw new FileBackupError(filePath)\n  }\n\n  const restoreBackupOnExit = () => restoreFileBackup(filePath)\n\n  process.on(\"exit\", restoreBackupOnExit)\n\n  try {\n    const result = await task()\n    process.removeListener(\"exit\", restoreBackupOnExit)\n    deleteFileBackup(filePath)\n    return result\n  } catch (error) {\n    process.removeListener(\"exit\", restoreBackupOnExit)\n    restoreFileBackup(filePath)\n    throw error\n  }\n}\n","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/packages/shadcn/src/utils/file-helper.ts#L56-L92","documentation":"Thrown as FileBackupError by withFileBackup when createFileBackup returns null. createFileBackup tries fsExtra.renameSync(filePath, filePath + '.bak'); if the rename throws (caught and returned as null), withFileBackup aborts rather than risk modifying a file it cannot restore. The error name is \"FileBackupError\" and the filePath is attached.","triggerScenarios":"withFileBackup(filePath, task) is called for a file that exists; createFileBackup attempts to rename it to a .bak sibling; renameSync fails (e.g. cross-device link, permission denied, read-only filesystem, file locked by another process, .bak already exists and target is busy).","commonSituations":"Project on a read-only mount or a filesystem that rejects rename; permission issues on the file or its directory; an existing .bak left over from a crashed run that cannot be overwritten; antivirus/process locking the file on Windows.","solutions":["Check write permissions on the file and its directory; chmod or chown as needed.","Remove any stale <file>.bak left from a previous failed run.","Ensure the file and its .bak target are on the same filesystem/device (rename does not cross devices).","Close any program holding an exclusive lock on the file, then retry."],"exampleFix":"# before — stale .bak or permission issue\nls -la components.json components.json.bak\n# after\nrm -f components.json.bak\nchmod u+w components.json\n# then re-run the shadcn command","handlingStrategy":"try-catch","validationCode":"import fsExtra from \"fs-extra\"\nfunction canBackup(filePath: string): boolean {\n  if (!fsExtra.existsSync(filePath)) return true // nothing to back up\n  try {\n    fsExtra.accessSync(filePath, fsExtra.constants.W_OK)\n    fsExtra.accessSync(path.dirname(filePath), fsExtra.constants.W_OK)\n    return !fsExtra.existsSync(`${filePath}.bak`)\n  } catch {\n    return false\n  }\n}","typeGuard":"const isBackupable = (filePath: string) => canBackup(filePath)","tryCatchPattern":"try {\n  await withFileBackup(filePath, task)\n} catch (e) {\n  if (e.name === \"FileBackupError\") {\n    // fix permissions / remove stale .bak, then retry\n  }\n  throw e\n}","preventionTips":["Ensure the project directory is writable and on a single device.","Remove stale *.bak files left by crashed runs before re-running.","Close editors/tools that lock files on Windows.","Run shadcn from a working copy the user owns."],"tags":["filesystem","backup","permissions","update"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}