[BUG] Credentials stored in literal ~ subdirectory of CWD when CLAUDE_CONFIG_DIR is set
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?
When launching Claude Code with CLAUDE_CONFIG_DIR pointing to a custom config directory:env CLAUDE_CONFIG_DIR="$HOME/.claude-personal" claude
Claude Code internally converts the path back to a ~-prefixed string (~/.claude-personal) and uses it in credential file paths without expanding ~. Since ~ is not expanded outside of a shell context, it is treated as a literal directory name relative to the current working directory.
The result: credentials are read from and written to <CWD>/~/.claude-personal/.credentials.json instead of the intended /home/user/.claude-personal/.credentials.json. A literal ~ subdirectory is created in whatever directory Claude Code was launched from.
This can be confirmed by deleting the <CWD>/~ directory — Claude Code immediately prompts for login again, proving that's where it was reading credentials from.
This does not reproduce when CLAUDE_CONFIG_DIR is unset (the default ~/.claude path is handled correctly).
What Should Happen?
CLAUDE_CONFIG_DIR is already set to a fully resolved absolute path. Claude Code should use it as-is for all file operations, including credential storage. If the path is ever converted to ~ shorthand internally, it must be re-expanded via os.homedir() or path.resolve() before any filesystem call.
CLAUDE_CONFIG_DIR=/home/user/.claude-personal → credentials at /home/user/.claude-personal/.credentials.json
Error Messages/Logs
Steps to Reproduce
- Run Claude Code with an explicit config dir:
env CLAUDE_CONFIG_DIR="$HOME/.claude-personal" claude
- Login when prompted
- Observe credentials written to
<CWD>/~/.claude-personal/.credentials.jsoninstead of/home/user/.claude-personal/.credentials.json - Deleting the
<CWD>/~directory causes Claude Code to prompt for login again, confirming this is where credentials are being read from
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.81 (Claude Code)
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗