Skip to content

[BUG] Global uninstall with CLAUDE_CONFIG_DIR deletes the default profile's files and keeps the selected profile's #3425

Open

Description

Reporting and investigating a bug need no permission. Before implementing a
substantive fix for inclusion in APM, obtain human scope approval and a review
contact on this issue. Trivial documentation corrections have standing
preapproval. See Contributing.

Describe the bug

Related to #3423 (same shared user lockfile, different command).

When a package is deployed to two Claude profiles, apm uninstall -g run with CLAUDE_CONFIG_DIR pointing to the second profile removes the package's files from the default profile (~/.claude). It refuses to remove the files of the selected profile, then exits 1 with the manifest and lockfile unchanged. Selected profile: files kept. Other profile: files deleted.

To Reproduce

Isolated HOME, a local package with one skill:

#!/bin/bash
R=$(mktemp -d)
export HOME=$R/home
unset CLAUDE_CONFIG_DIR APM_HOME
mkdir -p $HOME $R/pkg/.apm/skills/demo
printf 'name: demo\nversion: 0.1.0\ndescription: repro\nauthor: repro\n' > $R/pkg/apm.yml
printf -- '---\nname: demo\ndescription: Demo skill.\n---\nDemo.\n' > $R/pkg/.apm/skills/demo/SKILL.md
apm config set target claude
B=$HOME/profiles/b
show() { (cd $HOME && find .claude/skills profiles/b/skills -type f 2>/dev/null | sort); }

apm install -g $R/pkg >/dev/null
CLAUDE_CONFIG_DIR=$B apm install -g $R/pkg >/dev/null
apm install -g $R/pkg >/dev/null
echo "before:"; show
CLAUDE_CONFIG_DIR=$B apm uninstall -g $R/pkg; echo "exit=$?"
echo "after:"; show

Output (paths shortened to $R):

[*] Default install target set to: claude
before:
.claude/skills/demo/SKILL.md
profiles/b/skills/demo/SKILL.md
[i] Uninstalling from user scope (~/.apm/)
[>] Uninstalling 1 package(s)...
[+] _local/pkg - found in apm.yml
[i] Removed _local/pkg from apm_modules/
[i] Cleaned 2 stale deployed files for $R/pkg
[x] Uninstall could not remove tracked target files; manifest and lockfile ownership were preserved. Package directories may already have been removed.
[x]   - profiles/b/skills/demo
[x]   - profiles/b/skills/demo/SKILL.md
[x] Resolve or remove the listed files, then retry uninstall.
exit=1
after:
profiles/b/skills/demo/SKILL.md

After the command, ~/.apm/apm.yml still lists the package and deployed_files still lists both .claude/skills/demo/... and profiles/b/skills/demo/..., although ~/.claude/skills/demo is gone. The "Cleaned 2 stale deployed files" line refers to the default profile's files.

Expected behavior

Uninstalling from the selected profile removes that profile's files and does not touch files deployed to another profile. Because ~/.apm/apm.yml is shared per HOME, it needs deciding what should happen to the manifest entry and the other profile's lockfile rows when the package is still deployed elsewhere. The current result is the reverse of the intent, and the lockfile no longer matches the disk.

Environment (please complete the following information):

  • OS: Linux x86_64
  • Python Version: 3.12
  • APM Version: 0.35.0 (main 29200432), target claude

Additional context

APM_HOME cannot separate the state, because global commands do not read it (#2884). The install-side counterpart of this bug is #3423, with a proposed fix in #3424.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions