/login reports "Login successful" but token is never saved: ENOTDIR rmdir on stale .storage-write.lock file (2.1.277)

Status Open
Reported on v2.1.277
Maintainer reply None cached
Activity 1 comment · opened Sep 18, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

After updating to 2.1.277 (auto-update, 2026-09-18), every request failed with auth errors that cycled through API Error: 401 OAuth access token has been revoked, then Anthropic profile login expired, then Not logged in · Please run /login.

/login (in-session) and claude auth login (CLI) both complete the browser OAuth flow and print Login successful, but nothing is persisted. Immediately afterward:

  • claude auth status → "loggedIn": false, "authMethod": "none"
  • security find-generic-password -s "Claude Code-credentials" → item not found
  • ~/.claude/.credentials.json → does not exist

The Keychain itself is writable (verified with security add-generic-password / find / delete from the same shell). claude doctor reports "No installation issues found" while also reporting "Not signed in to claude.ai".

Root cause, from the debug log: the credential save fails because ~/.claude/.storage-write.lock existed as a regular file rather than a directory, so the lock cleanup rmdir threw ENOTDIR. The OAuth exchange had already succeeded, so the UI reported success while the token was silently dropped. Deleting the stale file fixed it on the next claude auth login.

Full logout, Keychain item deletion, removing ~/.claude/.credentials.json and ~/.config/anthropic, and restarting did not help until the lock file was removed. Side effects while in this state: all MCP servers showed "needs authentication", remote managed settings failed to fetch, and Remote Control reported "Sign-in is missing the user:profile scope" even though the login URL requested that scope.

What Should Happen?

Either of:

  1. The credential store should tolerate a stale .storage-write.lock that is a regular file (unlink it, or use a lock strategy that can't be left behind as a file), so the token save succeeds.
  2. At minimum, if the token save fails, /login and claude auth login should surface the error instead of printing Login successful. The Failed to save OAuth tokens error only appears in the --debug log, and claude doctor says "No installation issues found", so there is no user-visible signal pointing at the actual cause.

Error Messages/Logs

From ~/.claude/debug/<session>.txt during a /login in a `claude --debug` session:

2026-09-18T18:27:09.126Z [ERROR] Failed to save OAuth tokens: ENOTDIR: not a directory, rmdir '/Users/<user>/.claude/.storage-write.lock'
2026-09-18T18:27:09.747Z [DEBUG] [Bootstrap] Skipped: no usable OAuth, WIF, or API key
2026-09-18T18:27:28.457Z [ERROR] API error (attempt 1/11): Could not resolve authentication method. Expected one of apiKey, authToken, credentials, config, or profile to be set. Or for one of the "X-Api-Key" or "Authorization" headers to be explicitly omitted
2026-09-18T18:26:37.895Z [DEBUG] [Claude in Chrome] Disabled: OAuth token has no scope accepted by /api/oauth/validate (needs user:profile, user:office, or user:ccr_inference; ...)
2026-09-18T18:26:53.981Z [ERROR] [Anthropic telemetry] Failed to check metrics opt-out status: Auth error: no credential usable for the metrics opt-out check

CLI:

$ claude auth login
Opening browser to sign in…
Paste code here if prompted > Login successful.
$ claude auth status
{ "loggedIn": false, "authMethod": "none", "apiProvider": "firstParty", ... }

claude doctor (relevant lines):

Running: native (2.1.277)
Last update attempt: success → 2.1.277 (2026-09-18)
Managed settings (remote): not fetched — no usable credentials for the settings fetch
Organization policy: not fetched: no API key or claude.ai sign-in for the policy lookup
Remote Control: Not signed in to claude.ai / Sign-in is missing the user:profile scope
No installation issues found.

In-session messages seen over the course of the failure, in order:
- Please run /login · API Error: 401 OAuth access token has been revoked.
- Anthropic profile login expired · Run /login to use your claude.ai account instead, or re-authenticate the profile
- Not logged in · Please run /login
- ⚠ Remote managed settings failed to load (the profile credential could not authenticate the fetch)
- ⚠ 3 MCP servers need authentication · run /mcp

Steps to Reproduce

Reproduce the stale-lock state directly:

  1. claude auth logout
  2. touch ~/.claude/.storage-write.lock (a regular file, simulating whatever left it behind; in my case it appeared around the auto-update to 2.1.277)
  3. claude auth login and complete the browser flow → prints Login successful.
  4. claude auth status → "loggedIn": false
  5. claude --debug, run /login, then grep the newest ~/.claude/debug/*.txt for Failed to save OAuth tokens → ENOTDIR: not a directory, rmdir '.../.claude/.storage-write.lock'

Fix/workaround:

  1. rm -f ~/.claude/.storage-write.lock
  2. claude auth login → claude auth status now shows "loggedIn": true, "authMethod": "claude.ai"

I did not determine what originally created the lock as a file. Timeline: everything worked before the 2026-09-18 auto-update to 2.1.277; first symptom was the 401 revoked-token error in an existing session immediately after.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.277 (Claude Code), native install, darwin-arm64, commit 97305f0832e6

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

  • Auth: claude.ai account (Max subscription), no ANTHROPIC_API_KEY, no CLAUDE_CONFIG_DIR, no apiKeyHelper, no ANTHROPIC_PROFILE.
  • Keychain is the default login keychain and writes from the same shell succeed.
  • Plugins enabled: vercel, posthog (claude-plugins-official), last30days.
  • Existing issues searched: this is the macOS counterpart of #62600 ("Windows: stale lock directories block credential persistence after abnormal exit", closed as stale and locked, which asks for a new issue referencing it) and #71717. Same mechanism (mkdir-as-mutex lock left behind, /login reports success, credentials never written); the difference here is the stale .storage-write.lock was a regular file rather than a directory, so the failure surfaces as ENOTDIR on rmdir. Also likely related to #95386 and #87192.
  • Suggestion: have claude doctor / /doctor check for a stale *.lock in the config dir, since it currently reports a clean install in this state.
  • Candidate cause: a prior version was running in an active session when the auto-update to 2.1.277 landed, so a change in lock format between builds (file-based vs mkdir-based) is a likely way the lock ended up as a regular file. Nothing else writes to ~/.claude/ on this machine.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗