Skip to content

Troubleshooting

Before anything else, run the built-in check - it finds most of what follows:

claude-doctor

command not found: claude-profiles

The shell was started before the tooling was installed, or the source line is missing from your rc file.

exec $SHELL -l                       # reload this shell (PowerShell: open a new window)
grep claude-profiles ~/.zshrc        # or ~/.bashrc - is the source line there?

New terminals pick it up automatically; only already-open ones need reloading. Re-run sh ~/.claude-tools/install.sh if the line is genuinely absent - it is safe to run twice and will not duplicate anything.

Tab completion does not work

Completion needs zsh's completion system initialised. The zsh layer does this itself, but a later line in your ~/.zshrc can override it. Check that the source line is not being undone by a framework loaded afterwards (oh-my-zsh, prezto, starship), and try moving it to the end of the file.

Press Tab twice - the first press may only insert a common prefix.

A profile shows (not logged in) but I did log in

Most likely a typo created a second, empty profile. Profiles are created by being named, so claude-profile porofed silently makes porofed.

claude-profiles                      # look for a near-miss name
rm -rf ~/.claude-profiles/porofed    # remove the accidental one

On macOS the other cause is a moved profile directory. The Keychain entry is keyed to the absolute path, so relocating a profile orphans its credentials. Move it back, or log in again at the new path.

claude --resume cannot find the session I handed off

Three things to check, in order:

  1. Are you in the right directory? Sessions are looked up by working directory. cd to the folder the conversation belongs to.
  2. Are you on the right profile? claude-profile reports the active one.
  3. Did it land? claude-sessions -A -a shows every session in every profile - find the id and confirm which profile now holds it.

A handoff moves the session, so it is no longer resumable on the profile it came from. If you wanted it back there, hand it back, or rename the old copy:

cd ~/.claude/projects/<encoded-dir>
mv <session-id>.jsonl.bak <session-id>.jsonl

Use --copy next time to leave the original in place.

no session found for <dir>

claude-handoff and claude-sessions match on the working directory recorded inside the transcript. You are probably in a different directory from the one the conversation belongs to.

claude-sessions -a                   # every directory, to find where it lives
claude-handoff work -d ~/projects/<project-name>/api    # or point at the directory explicitly

Note the profile matters too: if a directory has a .claude-profile marker, cding there switches profiles, and the listing is profile-scoped. Use -A to search across all of them.

ambiguous session prefix

The prefix matched more than one session. The command lists the candidates - pass more characters.

claude-handoff work 0a90            # instead of: claude-handoff work 0

Everything worked yesterday and now something is off

If claude-sessions returns nothing, or --live stops working after a Claude Code update, check whether Claude Code changed something this tool reads:

claude-doctor --check-upstream

That reads one of your real transcripts and calls the usage endpoint once. A FAIL there means the format changed - please open an issue with the output.

Summaries are blank or the listing looks wrong

claude-sessions parses Claude Code's transcript format, which is internal and can change between releases. The other commands do not depend on it.

Check scan() in bin/claude-profiles.py against a recent transcript:

head -3 ~/.claude/projects/*/*.jsonl | python3 -m json.tool

The cd auto-switch is not firing

cat ~/projects/<project-name>/.claude-profile   # should contain just the profile name
claude-profile                        # what is active right now?

The nearest marker walking up from the current directory wins. A marker inside a subdirectory overrides one at the top of the tree. Trailing whitespace is stripped, but the name must match a directory under ~/.claude-profiles exactly - it is case-sensitive.

Changing an already-running claude is not possible; the profile is read at launch. Restart it.

The status line does not appear in Claude Code

claude-profiles statusline --install-all

Then start a new session - the setting is read at launch, so an already-open one will not pick it up.

If it still does not show, check two things. First, that the profile's settings.json has a statusLine entry. Second, that the command runs on its own:

echo '{}' | claude-profiles statusline --show profile,account

Remember settings are per-profile: installing it while on one profile does nothing for the others, which is what --install-all is for.

The status line shows the wrong profile

It reads CLAUDE_CONFIG_DIR from the environment Claude Code was launched with. If it disagrees with claude-profile, the session was started before you switched - the profile is fixed at launch. Exit and start it again.

The prompt indicator does not appear

CLAUDE_PROFILE_PROMPT=1 must be set before the line that sources the shell layer, because the layer reads it at load time.

grep -n "CLAUDE_PROFILE_PROMPT\|claude-profiles.zsh" ~/.zshrc
echo $RPROMPT     # expect: %F{242}$(claude_profile_prompt)%f

If RPROMPT is empty or something else, a later line in your rc file - a prompt theme, for instance - has overwritten it. Move the source line after whatever sets your prompt.

It stays silent on whichever profile is your normal one - default, or whatever CLAUDE_DEFAULT_PROFILE is set to. Set CLAUDE_PROFILE_SHOW_DEFAULT=1 to show it everywhere.

Both accounts hit their limits

Handoff moves a conversation, not quota. Check what you actually have:

claude-profiles                       # which accounts exist and are signed in

Then run /usage inside a session to see that account's remaining limit.

Clone or push fails: "Could not read from remote repository"

You have several GitHub accounts and plain git@github.com: resolved to the wrong one. Use the host alias from your ~/.ssh/config:

git remote set-url origin github-<alias>:<your-account>/<your-repo>.git
ssh -T github-<alias>                     # confirms which identity that alias uses

<alias> is whatever you named the Host entry in ~/.ssh/config.

Starting over

Removing a single profile logs out only that account:

rm -rf ~/.claude-profiles/work

Removing the tooling leaves every account intact:

rm -rf ~/.claude-tools
# then delete the source line from ~/.zshrc or ~/.bashrc

Your original account in ~/.claude is never touched by any of this.