{"record":{"id":"ba9a17d89c813257","repo":"eyaltoledano/claude-task-master","slug":"save-failed","errorCode":"SAVE_FAILED","errorMessage":"Failed to save context: ${(error as Error).message}","messagePattern":"Failed to save context: (.+?)","errorType":"error_code","errorClass":"AuthenticationError","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/auth/services/context-store.ts","lineNumber":104,"sourceCode":"\t\t\t\tlastUpdated: new Date().toISOString()\n\t\t\t};\n\n\t\t\t// Ensure directory exists\n\t\t\tconst dir = path.dirname(this.contextPath);\n\t\t\tif (!fs.existsSync(dir)) {\n\t\t\t\tfs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n\t\t\t}\n\n\t\t\t// Write atomically\n\t\t\tconst tempFile = `${this.contextPath}.tmp`;\n\t\t\tfs.writeFileSync(tempFile, JSON.stringify(updated, null, 2), {\n\t\t\t\tmode: 0o600\n\t\t\t});\n\t\t\tfs.renameSync(tempFile, this.contextPath);\n\n\t\t\tthis.logger.debug('Saved context to disk');\n\t\t} catch (error) {\n\t\t\tthrow new AuthenticationError(\n\t\t\t\t`Failed to save context: ${(error as Error).message}`,\n\t\t\t\t'SAVE_FAILED',\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Update user context (org/brief selection)\n\t */\n\tupdateUserContext(userContext: Partial<UserContext>): void {\n\t\tconst existing = this.getContext();\n\t\tconst currentUserContext = existing?.selectedContext || {};\n\n\t\tconst updated: UserContext = {\n\t\t\t...currentUserContext,\n\t\t\t...userContext,\n\t\t\tupdatedAt: new Date().toISOString()","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/auth/services/context-store.ts#L86-L122","documentation":"ContextStore.saveContext writes the auth context atomically (temp file with mode 0600, then rename). Any filesystem failure during that write is wrapped as AuthenticationError with code SAVE_FAILED and the OS error message. Callers include updateUserContext, clearUserContext, and all token-persisting auth flows.","triggerScenarios":"Writing the context file fails: unwritable directory, disk full, permission denied on the config path, target directory deleted mid-run, or fs.renameSync failing across filesystems.","commonSituations":"HOME/config directory not writable (sandboxed CI, read-only container); disk quota exceeded; antivirus/backup tooling locking the temp file; context path pointing to a nonexistent directory.","solutions":["Check the config directory exists and is writable (mkdir -p, check permissions)","Free disk space / check quota if ENOSPC reported","Inspect the wrapped OS message after 'Failed to save context:' for the exact errno","Run as a user with write access to ~/.task-master (or the configured config dir)","Catch AuthenticationError code SAVE_FAILED around auth operations"],"exampleFix":"// before\nawait auth.authenticateWithCode(code); // SAVE_FAILED if dir missing\n// after\nimport fs from 'fs';\nconst dir = path.dirname(contextPath);\nif (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\nawait auth.authenticateWithCode(code);","handlingStrategy":"try-catch","validationCode":"import fs from 'fs';\nconst dir = path.dirname(contextPath);\nif (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\nfs.accessSync(dir, fs.constants.W_OK);","typeGuard":"function isSaveFailedError(e: unknown): e is AuthenticationError {\n  return e instanceof AuthenticationError && e.code === 'SAVE_FAILED';\n}","tryCatchPattern":"try {\n  await auth.authenticateWithCode(code);\n} catch (e) {\n  if (isSaveFailedError(e)) {\n    console.error('Cannot write context file:', e.message);\n    console.error('Check permissions/disk space for the config directory.');\n  } else throw e;\n}","preventionTips":["Ensure the config directory exists and is writable before auth flows","Watch for ENOSPC (disk full) in CI/containers with small ephemeral disks","Avoid running as different users that create root-owned context files","Backup/restore context files with matching ownership and 0600 permissions"],"tags":["filesystem","auth","persistence"],"backgroundTag":"context-save-failed","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}