{"record":{"id":"fe9c62d6ae6eb15e","repo":"withastro/astro","slug":"failed-to-write-lock-file-message","errorCode":null,"errorMessage":"Failed to write lock file: ${message}","messagePattern":"Failed to write lock file: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/core/dev/lockfile.ts","lineNumber":175,"sourceCode":"\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Write the lock file to disk.\n */\nexport function writeLockFile(root: URL, data: LockFileData, command: ServerCommand = 'dev'): void {\n\tconst lockFileURL = getLockFileURL(root, command);\n\tconst dirPath = fileURLToPath(new URL('.astro/', root));\n\ttry {\n\t\tif (!existsSync(dirPath)) {\n\t\t\tmkdirSync(dirPath, { recursive: true });\n\t\t}\n\t\twriteFileSync(lockFileURL, serializeLockFile(data), 'utf-8');\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to write lock file: ${message}`);\n\t}\n}\n\n/**\n * Remove the lock file from disk. No-op if it doesn't exist.\n */\nexport function removeLockFile(root: URL, command: ServerCommand = 'dev'): void {\n\tconst lockFileURL = getLockFileURL(root, command);\n\ttry {\n\t\tunlinkSync(lockFileURL);\n\t} catch (err: any) {\n\t\t// ENOENT means the file doesn't exist, which is fine.\n\t\t// Any other error (permissions, etc.) should be surfaced.\n\t\tif (err?.code !== 'ENOENT') {\n\t\t\tthrow err;\n\t\t}\n\t}\n}","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/withastro/astro/blob/157c500c38faa7ecf1251adbaeefcd109470d75c/packages/astro/src/core/dev/lockfile.ts#L157-L193","documentation":"`writeLockFile` creates the `.astro/` directory and writes the dev/build session lock file with sync fs calls. Any failure from `mkdirSync`/`writeFileSync` (permissions, read-only mount, disk full, file held by another process) is caught and rethrown as a plain Error prefixed \"Failed to write lock file:\" with the underlying message.","triggerScenarios":"The `.astro` directory or lock file is not writable: EACCES/EPERM from ownership mismatch, a read-only bind mount in Docker/CI, ENOSPC when the disk is full, or a lock file held open by another process.","commonSituations":"Running the dev server in a container with a read-only project volume; an earlier `sudo astro dev` left root-owned `.astro`; two processes racing on the same root; CI runners with full disks.","solutions":["Fix ownership/permissions: `sudo chown -R $(whoami) .astro` or `chmod -R u+w .astro`.","Delete a stale or root-owned lock: `rm -rf .astro` (it is regenerated).","Ensure the project directory is writable in Docker/CI (do not mount it read-only).","Free disk space and avoid running multiple dev/build processes against the same root simultaneously."],"exampleFix":"# before\nastro dev   # Failed to write lock file: EACCES: permission denied\n\n# after\nrm -rf .astro\nchmod u+w .\nastro dev","handlingStrategy":"validation","validationCode":"// Preflight before starting dev/build: .astro must be writable\nimport { accessSync, constants, mkdirSync } from 'node:fs';\nmkdirSync('.astro', { recursive: true });\ntry {\n  accessSync('.astro', constants.W_OK);\n} catch {\n  console.error('.astro directory is not writable — fix permissions or the mount.');\n  process.exit(1);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Mount the project directory read-write in Docker/CI, or write `.astro` to a writable location via root.","Never run the dev server under sudo; it leaves root-owned files behind.","Run one dev/build process per project root at a time."],"tags":["filesystem","dev-server","permissions","lockfile"],"backgroundTag":"file-write-permission-denied","analyzedSha":"157c500c38faa7ecf1251adbaeefcd109470d75c","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}