slopus/happy · error
Failed to logout: ${error instanceof Error ? error.message :
Error message
Failed to logout: ${error instanceof Error ? error.message : 'Unknown error'} What it means
handleAuthLogout wraps any exception from the logout flow — removing credential files/directories, server session revocation — into 'Failed to logout: <message>'. It's an umbrella error: the local auth state may or may not have been cleared depending on where it failed.
Source
Thrown at packages/happy-cli/src/commands/auth.ts:159
rl.close();
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
try {
// Stop daemon if running
try {
await stopDaemon();
console.log(chalk.gray('Stopped daemon'));
} catch { }
// Remove entire happy directory (as current logout does)
if (existsSync(happyDir)) {
rmSync(happyDir, { recursive: true, force: true });
}
console.log(chalk.green('✓ Successfully logged out'));
console.log(chalk.gray(' Run "happy auth login" to authenticate again'));
} catch (error) {
throw new Error(`Failed to logout: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
} else {
console.log(chalk.blue('Logout cancelled'));
}
}
async function handleAuthStatus(): Promise<void> {
const credentials = await readCredentials();
const settings = await readSettings();
console.log(chalk.bold('\nAuthentication Status\n'));
if (!credentials) {
console.log(chalk.red('✗ Not authenticated'));
console.log(chalk.gray(' Run "happy auth login" to authenticate'));
return;
}
View on GitHub (pinned to b824cd0a46)
Solutions
- Read the wrapped message to see if it's a filesystem (EPERM/EBUSY) or network error
- Close other happy processes/daemons (`happy daemon stop`) and retry logout
- Manually remove the credentials directory (e.g. rm -rf ~/.happy) if deletion keeps failing
- For network errors, note local credentials may already be cleared; re-login when back online
Example fix
// before $ happy auth logout Error: Failed to logout: EPERM: operation not permitted, unlink '~/.happy/access.key' // after $ happy daemon stop $ happy auth logout # or: rm -rf ~/.happy && happy auth login
Defensive patterns
Strategy: try-catch
Validate before calling
import { accessSync, constants } from 'node:fs';
try {
accessSync(happyDir, constants.W_OK);
} catch {
console.error('Cannot write to auth directory; fix permissions on ' + happyDir);
process.exit(1);
} Try / catch
try {
await handleAuthLogout(argv);
} catch (error) {
const msg = (error as Error).message;
if (msg.includes('EPERM') || msg.includes('EBUSY')) {
console.error('Close other happy processes and retry logout.');
} else if (msg.includes('network') || msg.includes('fetch')) {
console.warn('Server revocation failed; local credentials may already be removed.');
} else { throw error; }
} Prevention
- Stop the happy daemon before logging out
- Ensure the auth directory (~/.happy) is writable and not on a read-only mount
- Treat logout as idempotent: missing credentials should not be an error
When it happens
Trigger: The `happy auth logout` command's try block throws: rmSync failing on the happy dir (permissions, file locks), or an error while contacting the server to invalidate the session.
Common situations: Read-only filesystem or sandboxed environment blocking deletion of ~/.happy; another happy process holding files open (EBUSY/EPERM); network failure while revoking the session server-side.
Related errors
- Claude local launcher not found. Please ensure HAPPY_PROJECT
- Failed to resume Codex thread ${opts.threadId}: ${reason}
- Failed to acquire settings lock after ${MAX_LOCK_ATTEMPTS *
- Saved session path does not exist: ${launch.cwd}
- Cannot resume historical Happy sessions through legacy accou
AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31).
Data as JSON: /api/errors/8d2875d5576e2c88.
Report an issue: GitHub.