{"record":{"id":"d3ccb3824e4a1287","repo":"eyaltoledano/claude-task-master","slug":"failed-to-get-storage-stats-error-message","errorCode":null,"errorMessage":"Failed to get storage stats: ${error.message}","messagePattern":"Failed to get storage stats: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/storage/adapters/file-storage/file-storage.ts","lineNumber":116,"sourceCode":"\n\t\t\treturn {\n\t\t\t\ttotalTasks,\n\t\t\t\ttotalTags: tags.length,\n\t\t\t\tlastModified: stats.mtime.toISOString(),\n\t\t\t\tstorageSize: 0, // Could calculate actual file sizes if needed\n\t\t\t\ttagStats\n\t\t\t};\n\t\t} catch (error: any) {\n\t\t\tif (error.code === 'ENOENT') {\n\t\t\t\treturn {\n\t\t\t\t\ttotalTasks: 0,\n\t\t\t\t\ttotalTags: 0,\n\t\t\t\t\tlastModified: new Date().toISOString(),\n\t\t\t\t\tstorageSize: 0,\n\t\t\t\t\ttagStats: []\n\t\t\t\t};\n\t\t\t}\n\t\t\tthrow new Error(`Failed to get storage stats: ${error.message}`);\n\t\t}\n\t}\n\n\t/**\n\t * Load tasks from the single tasks.json file for a specific tag\n\t * Enriches tasks with complexity data from the complexity report\n\t */\n\tasync loadTasks(tag?: string, options?: LoadTasksOptions): Promise<Task[]> {\n\t\tconst filePath = this.pathResolver.getTasksPath();\n\t\tconst resolvedTag = tag || 'master';\n\n\t\ttry {\n\t\t\tconst rawData = await this.fileOps.readJson(filePath);\n\t\t\tlet tasks = this.formatHandler.extractTasks(rawData, resolvedTag);\n\n\t\t\t// Apply filters if provided\n\t\t\tif (options) {\n\t\t\t\t// Filter by status if specified","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/storage/adapters/file-storage/file-storage.ts#L98-L134","documentation":"getStats() aggregates task counts, tag statistics, and storage size by reading the tasks.json file. If any underlying file operation (read, parse, or stat) fails with an error other than ENOENT, the method wraps it in this generic error so callers get a uniform failure message for storage-statistics reads.","triggerScenarios":"Corrupt or malformed JSON in .taskmaster/tasks.json, permission errors on the tasks file or its directory, readJson throwing a non-ENOENT error (e.g. EACCES, EISDIR, JSON parse errors), or a failure in formatHandler.extractTags/extractMetadata while building stats.","commonSituations":"Tasks file truncated by a crashed editor or concurrent write, .taskmaster directory permissions changed after cloning a repo as another user, tasks.json hand-edited into invalid JSON, or the path resolving to a directory instead of a file.","solutions":["Validate/repair .taskmaster/tasks.json (run it through a JSON linter or restore from git)","Check file and directory permissions on .taskmaster/ and fix with chmod/chown","Read the underlying error.message in the thrown error to identify the real cause (ENOENT is already handled and returns empty stats)","Ensure no concurrent process is writing tasks.json while stats are computed"],"exampleFix":"// before: hand-edited, trailing comma in tasks.json\n{ \"master\": { \"tasks\": [ { \"id\": 1, \"title\": \"x\", }, ] } }\n// after: valid JSON\n{ \"master\": { \"tasks\": [ { \"id\": 1, \"title\": \"x\" } ] } }","handlingStrategy":"try-catch","validationCode":"// Verify tasks.json exists and parses before calling getStats\nimport { readFileSync } from 'fs';\nfunction canReadStats(path = '.taskmaster/tasks.json') {\n  try { JSON.parse(readFileSync(path, 'utf8')); return true; }\n  catch { return false; }\n}\nif (!canReadStats()) { /* repair file first */ }","typeGuard":"function isStorageError(e: unknown): e is Error & { message: string } {\n  return e instanceof Error && e.message.startsWith('Failed to get storage stats:');\n}","tryCatchPattern":"try {\n  const stats = await storage.getStats();\n} catch (e) {\n  if (isStorageError(e)) {\n    const cause = e.message.replace('Failed to get storage stats: ', '');\n    if (cause.includes('ENOENT')) return emptyStats; // file not created yet\n    console.error('Storage stats failed, cause:', cause); // parse/permission issue\n  } else throw e;\n}","preventionTips":["Never hand-edit tasks.json while the app is running","Keep .taskmaster/ under version control so corrupt files can be restored","Validate JSON after any external tool touches tasks.json","Ensure the process user has read access to .taskmaster/"],"tags":["storage","file-io","json-parse"],"backgroundTag":"file-read-failed","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}