Skip to content

[BUG] Native installer self-update (2.1.111 → 2.1.112) truncates ~/.bash_profile, ~/.bash_aliases, ~/.zshrc to 0 bytes #49615

@Gr3yF0x87

Description

@Gr3yF0x87

Preflight Checklist

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

What's Wrong?

During a background self-update from 2.1.111 to 2.1.112, the Claude Code native installer truncated three shell rc files in $HOME to 0 bytes:

  • ~/.bash_profile
  • ~/.bash_aliases
  • ~/.zshrc

The empty ~/.bash_profile silently breaks SSH login shells: bash's login-shell lookup order uses ~/.bash_profile if it exists (even at 0 bytes) and skips ~/.profile. On Ubuntu, ~/.profile is what sources ~/.bashrc. Result: every new SSH login shell loses all aliases, $PATH additions from .bashrc, and exported env vars.

The update also created empty ~/.claude/agents/ and ~/.claude/commands/ dirs and rewrote ~/.claude/plugins/installed_plugins.json -- all in the same second. No ~/.bash_profile.bak (or similar) was left behind. Pre-existing content in .bash_aliases/.zshrc (if any) would be destroyed without warning.

What Should Happen?

The installer should never write to ~/.bash_profile, ~/.bash_aliases, or ~/.zshrc. If shell integration is intentionally being installed, it should (a) append rather than truncate, (b) back up the original to a .pre-claude or .bak file, and (c) be documented in the release notes and visible to the user at upgrade time.

Error Messages/Logs

# File timestamps showing simultaneous damage (America/New_York, -0400).
# Observed after the shell rc files had already been repaired, so only
# the ~/.claude/ side still carries exact sub-second timestamps. The
# three shell files were observed at 0 bytes with mtime "Apr 16 19:36"
# -- same minute as the ~/.claude/ skeleton rewrite below.

$ stat -c '%y %s %n' ~/.claude/agents ~/.claude/commands ~/.claude/plugins/installed_plugins.json
2026-04-16 19:36:12.524618930 -0400   4096   $HOME/.claude/agents             (empty dir)
2026-04-16 19:36:12.524618930 -0400   4096   $HOME/.claude/commands           (empty dir)
2026-04-16 19:36:21.633640893 -0400    452   $HOME/.claude/plugins/installed_plugins.json

$ ls -la ~/.bash_profile ~/.bash_aliases ~/.zshrc   # as observed BEFORE repair
-rw-rw-r-- 1 user user 0 Apr 16 19:36 $HOME/.bash_aliases
-rw-rw-r-- 1 user user 0 Apr 16 19:36 $HOME/.bash_profile
-rw-rw-r-- 1 user user 0 Apr 16 19:36 $HOME/.zshrc

# Installed versions dir -- self-update mid-flight
$ ls -la ~/.local/share/claude/versions/
-rwxr-xr-x 1 user user 234871424 Apr 15 19:25 2.1.110
-rwxr-xr-x 1 user user 235842176 Apr 16 12:46 2.1.111
-rwxr-xr-x 1 user user 235846272 Apr 16 15:56 2.1.112

# Symlink flipped to 2.1.112 ~5 minutes AFTER the shell files were truncated
$ ls -la ~/.local/bin/claude
lrwxrwxrwx 1 user user 49 Apr 16 19:41 $HOME/.local/bin/claude -> $HOME/.local/share/claude/versions/2.1.112

# Symptom on next SSH login
$ ssh host
host$ claude --version
bash: claude: command not found     # alias gone, ~/.local/bin missing from PATH
host$ echo $MY_CUSTOM_ENV_VAR
                                    # empty -- .bashrc exports never ran

Steps to Reproduce

Unable to reproduce deterministically without a second clean host. Observed sequence:

  1. Host running Claude Code 2.1.111 via native installer (~/.local/bin/claude symlink).
  2. Claude Code background-downloads 2.1.112 to ~/.local/share/claude/versions/2.1.112 while an interactive session is active.
  3. Self-update post-install step fires at some point during or at the end of the active session.
  4. That step:
    a. Re-skeletons ~/.claude/agents/ and ~/.claude/commands/ (empty dirs).
    b. Rewrites ~/.claude/plugins/installed_plugins.json.
    c. Truncates ~/.bash_profile, ~/.bash_aliases, ~/.zshrc to 0 bytes.
    d. Terminates the active session.
  5. ~5 minutes later, ~/.local/bin/claude symlink is atomically flipped to 2.1.112.
  6. User opens a new SSH session: login shell reads empty ~/.bash_profile, skips ~/.profile, does not source ~/.bashrc. Aliases/PATH/env are gone.

Likely trigger: any 2.1.111 -> 2.1.112 native-installer auto-update on Linux where $HOME is the user's real home dir.

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.111

Claude Code Version

2.1.112

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Other

Additional Information

Host: Ubuntu 24.04.4 LTS (noble), bash 5.2.21, native installer path ~/.local/share/claude/versions/.

Workaround: rm ~/.bash_profile ~/.bash_aliases ~/.zshrc. Ubuntu's default ~/.profile then sources ~/.bashrc correctly on login.

The bug is especially nasty because:

  1. No visible error at upgrade time -- the update "succeeds."
  2. Existing SSH sessions keep working (they have .bashrc already sourced in-memory).
  3. Only the NEXT new SSH login reveals the break, making it easy to attribute to unrelated causes.
  4. If ~/.bash_aliases or ~/.zshrc had user content, it is silently lost with no backup.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions