{"record":{"id":"d659d5e83ae72109","repo":"eyaltoledano/claude-task-master","slug":"failed-to-read-file-filepath-error-message","errorCode":null,"errorMessage":"Failed to read file ${filePath}: ${error.message}","messagePattern":"Failed to read file (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/storage/adapters/file-storage/file-operations.ts","lineNumber":65,"sourceCode":"\t\t}\n\t\treturn writer;\n\t}\n\n\t/**\n\t * Read and parse JSON file\n\t */\n\tasync readJson(filePath: string): Promise<any> {\n\t\ttry {\n\t\t\tconst content = await fs.readFile(filePath, 'utf-8');\n\t\t\treturn JSON.parse(content);\n\t\t} catch (error: any) {\n\t\t\tif (error.code === 'ENOENT') {\n\t\t\t\tthrow error; // Re-throw ENOENT for caller to handle\n\t\t\t}\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\tthrow new Error(`Invalid JSON in file ${filePath}: ${error.message}`);\n\t\t\t}\n\t\t\tthrow new Error(`Failed to read file ${filePath}: ${error.message}`);\n\t\t}\n\t}\n\n\t/**\n\t * Write JSON file with atomic operation and cross-process locking.\n\t * Uses steno for atomic writes and proper-lockfile for cross-process safety.\n\t * WARNING: This replaces the entire file. For concurrent modifications,\n\t * use modifyJson() instead to prevent lost updates.\n\t */\n\tasync writeJson(\n\t\tfilePath: string,\n\t\tdata: FileStorageData | any\n\t): Promise<void> {\n\t\t// Ensure file exists for locking (proper-lockfile requires this)\n\t\tawait this.ensureFileExists(filePath);\n\n\t\t// Acquire cross-process lock\n\t\tlet release: (() => Promise<void>) | null = null;","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/storage/adapters/file-storage/file-operations.ts#L47-L83","documentation":"readJson() wraps any read failure that is neither ENOENT nor a JSON SyntaxError into 'Failed to read file <path>: <reason>'. This covers filesystem-level problems (permissions, EISDIR, EACCES, I/O errors) encountered while reading the file, as opposed to parse problems.","triggerScenarios":"Calling readJson (or data/rawData/stateData accessors) when fs.readFile fails for a non-missing-file reason: the path is a directory, the process lacks read permission, the file is on a detached/unmounted volume, or an EBUSY/EIO condition occurs.","commonSituations":"Running under a different user (CI, Docker) without permissions on ~/.taskmaster; the configured storage path accidentally points at a directory; a Windows file lock held by another process; NFS/disk errors in containerized environments.","solutions":["Check the underlying reason in error.message (e.g. EACCES, EISDIR) and fix it — correct the path if it points at a directory.","Fix permissions: chmod/chown the file or its parent directory so the running user can read it.","Verify the storage root path configuration points to the intended directory containing the JSON files.","If running in Docker/CI, mount the .taskmaster directory with correct ownership (match the container user's UID/GID)."],"exampleFix":"// before\nls -l ~/.taskmaster/tasks.json  # -rw------- root root\n// after\nsudo chown $(whoami) ~/.taskmaster/tasks.json\nchmod u+rw ~/.taskmaster/tasks.json","handlingStrategy":"try-catch","validationCode":"import { access, constants } from 'fs/promises';\nexport async function isReadableFile(filePath: string): Promise<boolean> {\n  try { await access(filePath, constants.R_OK); return true; } catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const data = await fileOps.readJson(filePath);\n} catch (err: any) {\n  if (err.code === 'ENOENT') return defaultValue;\n  if (err.message.startsWith('Failed to read file')) {\n    console.error(`Cannot read ${filePath}: check permissions/path (${err.message})`);\n    throw err;\n  }\n  throw err;\n}","preventionTips":["Ensure the process user owns or can read ~/.taskmaster (chown in Docker entrypoint to match UID).","Check that configured storage paths point to files, not directories.","Avoid storing .taskmaster on flaky network mounts; prefer local disk.","Run a preflight access(R_OK) check when accepting a custom project path."],"tags":["filesystem","file-storage","permissions","io"],"backgroundTag":"file-read-failed","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}