eyaltoledano/claude-task-master · error · AuthenticationError

SAVE_FAILED

SAVE_FAILED

Error message

Failed to save context: ${(error as Error).message}

What it means

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.

Source

Thrown at packages/tm-core/src/modules/auth/services/context-store.ts:104

				lastUpdated: new Date().toISOString()
			};

			// Ensure directory exists
			const dir = path.dirname(this.contextPath);
			if (!fs.existsSync(dir)) {
				fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
			}

			// Write atomically
			const tempFile = `${this.contextPath}.tmp`;
			fs.writeFileSync(tempFile, JSON.stringify(updated, null, 2), {
				mode: 0o600
			});
			fs.renameSync(tempFile, this.contextPath);

			this.logger.debug('Saved context to disk');
		} catch (error) {
			throw new AuthenticationError(
				`Failed to save context: ${(error as Error).message}`,
				'SAVE_FAILED',
				error
			);
		}
	}

	/**
	 * Update user context (org/brief selection)
	 */
	updateUserContext(userContext: Partial<UserContext>): void {
		const existing = this.getContext();
		const currentUserContext = existing?.selectedContext || {};

		const updated: UserContext = {
			...currentUserContext,
			...userContext,
			updatedAt: new Date().toISOString()

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Check the config directory exists and is writable (mkdir -p, check permissions)
  2. Free disk space / check quota if ENOSPC reported
  3. Inspect the wrapped OS message after 'Failed to save context:' for the exact errno
  4. Run as a user with write access to ~/.task-master (or the configured config dir)
  5. Catch AuthenticationError code SAVE_FAILED around auth operations

Example fix

// before
await auth.authenticateWithCode(code); // SAVE_FAILED if dir missing
// after
import fs from 'fs';
const dir = path.dirname(contextPath);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
await auth.authenticateWithCode(code);
Defensive patterns

Strategy: try-catch

Validate before calling

import fs from 'fs';
const dir = path.dirname(contextPath);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
fs.accessSync(dir, fs.constants.W_OK);

Type guard

function isSaveFailedError(e: unknown): e is AuthenticationError {
  return e instanceof AuthenticationError && e.code === 'SAVE_FAILED';
}

Try / catch

try {
  await auth.authenticateWithCode(code);
} catch (e) {
  if (isSaveFailedError(e)) {
    console.error('Cannot write context file:', e.message);
    console.error('Check permissions/disk space for the config directory.');
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/ba9a17d89c813257. Report an issue: GitHub.