Troubleshooting
Use this guide when something feels off and you are not sure if it is AgentSync, your environment, or your configuration.
Healthy baseline first. In your project root, these three should all pass:
agentsync --versionagentsync doctoragentsync statusIf all three pass and the behavior still looks wrong, work through the sections below in order. Most reports turn out to be one of these: a shadowed binary, a missing PATH entry, expected status drift, or a doctor warning that already names the fix.
Installed a new version but --version shows an old one
Section titled “Installed a new version but --version shows an old one”This is the most confusing one because the installer says success and the CLI disagrees.
Typical symptoms
pnpm add -g @dallay/agentsync# global:# + @dallay/agentsync 1.50.0
agentsync --version# agentsync 1.32.0The new package installed correctly. A different, older binary is winning in your PATH.
Why it happens
AgentSync can be installed two independent ways:
- npm wrapper (
npm / pnpm / yarn / bun -g) — downloads a platform binary and exposes it from the package-manager globalbindirectory, for example~/Library/pnpm/bin/agentsync. - Rust binary (
cargo install agentsync) — compiles and drops a standalone binary into~/.cargo/bin/agentsync.
Those two binaries do not update each other. If ~/.cargo/bin appears earlier in PATH than the pnpm/npm global bin, the shell keeps running the old Rust binary even after a successful pnpm add -g.
Diagnose it
# 1. Which binary is actually running?which agentsyncls -la "$(which agentsync)"
# 2. What does the package-manager binary report directly?# Adjust the path to your setup if needed.~/Library/pnpm/bin/agentsync --version
# 3. Confirm the shadowed copyls -la ~/.cargo/bin/agentsyncecho "$PATH" | tr ':' '\n' | nlWhat you want to see:
which agentsyncpoints to the binary you intend to use.- The direct-path
--versionprints the new version (for example1.50.0). - An old dated binary exists in the earlier
PATHentry (for example a 7 MB file from months ago in~/.cargo/bin).
Fix it: keep the npm wrapper, remove the old cargo binary
If you already manage AgentSync through pnpm/npm, the cleanest fix is to remove the stale standalone binary:
rm ~/.cargo/bin/agentsynchash -r # clear the shell's cached command locationswhich agentsyncagentsync --version # should now print the new versionIf you intentionally want to keep both:
alias agentsync='~/Library/pnpm/bin/agentsync'agentsync --versionAdd the alias to your shell profile (for example ~/.zshrc) so it survives restarts.
Prevent it
- Pick one install method per machine: either the npm wrapper or
cargo install, not both. - After switching methods, verify with
which agentsyncandagentsync --versionbefore reporting a version bug. - In CI, prefer a one-off runner (
npx,pnpm dlx,bunx) so no global binary can shadow the pinned version:
npx @dallay/agentsync --versionpnpm dlx @dallay/agentsync --versionyarn dlx @dallay/agentsync --versionbunx @dallay/agentsync --versionagentsync: command not found after a global install
Section titled “agentsync: command not found after a global install”The package installed, but its bin directory is not on PATH.
# Where did pnpm put the binary?pnpm root -gls -la ~/Library/pnpm/bin/agentsync
# Is that directory on PATH?echo "$PATH" | tr ':' '\n' | grep -i pnpmFixes:
- Add the global bin directory to your shell profile (
export PATH="$HOME/Library/pnpm/bin:$PATH"for pnpm, or the equivalent for npm/yarn/bun), reload the shell, and retry. - Or skip global installs entirely and use a one-off runner in each project:
npx @dallay/agentsync statuspnpm dlx @dallay/agentsync statusyarn dlx @dallay/agentsync statusbunx @dallay/agentsync statusagentsync status reports drift
Section titled “agentsync status reports drift”status is supposed to complain when the filesystem drifted from agentsync.toml. Read its verdict literally:
| Status | Meaning | Typical fix |
|---|---|---|
✔ OK |
Symlink exists and points to the expected source | Nothing to do |
✗ Incorrect link |
Symlink points somewhere else | Run agentsync apply, or apply --clean if you want a full recreate |
! Missing |
Destination does not exist | Run agentsync apply |
· Exists but not a symlink |
A regular file or directory blocks the destination | Back up or remove the blocker, then agentsync apply |
Useful pattern before writing anything:
agentsync statusagentsync apply --dry-runagentsync applyagentsync statusScope the repair when you only care about one agent:
agentsync apply --agents claude --dry-runagentsync apply --agents claudeFor the full schema, exit codes, and CI usage (status --json), see the Status Output reference.
agentsync doctor warns about config or environment
Section titled “agentsync doctor warns about config or environment”doctor names the problem class for you. Common hits:
- Missing
agentsync.tomlor TOML syntax error — run from the project root, or pass--project-root, and validate the TOML. - Target source does not exist — the
sourcepath in your config has a typo or the file was never created under.agents/. module-maptarget with no mappings — the target is misconfigured; add mappings or disable it.- Destination conflicts — same destination claimed twice; narrow it to one owner.
.gitignoreaudit findings — marker-aware parsing found a stale or unexpected managed block. Decide your team policy first in the Gitignore Team Workflows guide.- MCP server not executable — the configured MCP command is missing or not on
PATH. - Unmanaged Claude skills — content exists in
.claude/skills/that no target manages. Either adopt it intoagentsync.tomlor leave it unmanaged on purpose. - Skills mode mismatch — a skills target is configured as
symlink-contentswhile the destination is already the expected directory symlink.statusstaysOKand prints a hint; switch that target tosymlinkto avoid churn.
Run order that separates config problems from environment problems:
agentsync doctoragentsync statusagentsync apply --dry-runagentsync apply fails to create symlinks
Section titled “agentsync apply fails to create symlinks”If apply fails with a symlink-permission error on Windows, fix the shell setup before treating it as an AgentSync bug: Developer Mode or Administrator shell, correct native-versus-WSL context, then apply again. Full steps live in the Windows Symlink Setup guide.
On macOS or Linux, the usual causes are:
- A regular file or directory already occupies the destination (
statusshowsExists but not a symlink). Back it up, remove it, and re-runapply. - The configured
sourcedoes not exist.doctortells you which one. - You are running from the wrong directory. Pass
-p /path/to/repoorcdinto the project root.
Clean retry when you changed approach and want a fresh reconcile:
agentsync cleanagentsync applyagentsync statusUse clean only when you intend to remove managed links before recreating them.
.gitignore replacement cannot preserve filesystem metadata
Section titled “.gitignore replacement cannot preserve filesystem metadata”Updates to an existing .gitignore use an atomic replacement. On Unix, AgentSync preserves owner/group and mode; Linux POSIX ACLs and macOS/FreeBSD ACLs are handled explicitly. On Windows, AgentSync preserves and verifies both the original owner SID and DACL. If Windows does not allow the original owner to be assigned to the staged file, or the resulting owner SID/DACL cannot be verified, AgentSync refuses the replacement and leaves the original .gitignore intact. On another Unix target, an update that would replace an existing .gitignore fails closed rather than publishing a file with unverified ACLs; create or update it on a supported target, or manage the block manually.
On Unix, if the process cannot preserve the original owner/group, AgentSync refuses the atomic replacement. It does not fall back to truncating the existing file in place, because that would lose atomicity and change behavior for hard-linked files. A file created by the current process with matching ownership does not need an ownership change.
I applied and want to go back
Section titled “I applied and want to go back”apply backs up any regular file or directory it replaces into a .bak sibling (e.g., CLAUDE.md → CLAUDE.md.bak). revert removes the managed symlinks and moves those backups back into place:
agentsync revert --dry-runagentsync revertagentsync statusScope it to one agent, or keep the backups for inspection:
agentsync revert --agents claudeagentsync revert --keep-backups--keep-backups is supported on Unix only. On Windows it is rejected before revert changes managed links or backup files; run normal agentsync revert to move the original .bak and preserve its inherited permissions.
Know the limits:
- Destinations that did not exist before
applyare simply unlinked (there is nothing to restore). - A backup is never restored over a real file that appeared after the backup was taken.
- For
symlink-contents,revertremoves managed child links but may leave the destination directory empty because it cannot infer whether the container existed beforeapply. - For
nested-glob,revertmust rediscover current source matches to verify each destination. If a source file was deleted afterapply, its symlink plus.baktwin are restored via a dest-side orphan scan, provided the symlink dangles into the configured source root, the.baksibling is a regular file, and the destination matches the target’s template. If the configured source root is missing or unsafe, it reports an incomplete revert, leaves destinations it cannot identify untouched, and keeps the managed.gitignoreblock. Restore the source root and retry, then inspect any remaining links manually. cleandoes not restore backups — it only deletes managed links. Userevertwhen you want your originals back.- On a complete, unfiltered symlink-revert run,
revertalso removes the AgentSync-managed.gitignoreblock; with--agents, a narrowingdefault_agents, or a symlink-revert error/skip, the block is left alone because managed destinations may remain. An MCP snapshot skip does not prevent this cleanup. Re-runapplyto reconcile it.
See the CLI Reference for all revert flags.
MCP revert skips a config or retains its journal
Section titled “MCP revert skips a config or retains its journal”MCP restore is conditional to protect changes made after apply. If the config changed, became a symlink, fails journal validation, or a shared destination is only partly selected, revert preserves the MCP file and journal and reports a skip or error. It does not perform a three-way merge.
- Back up or safely resolve later edits before retrying. Do not delete the journal to force a restore.
- If the later edit is intentional and another
applymust proceed, back up the MCP config and useagentsync apply --rebase-mcp-journal. This explicit opt-in keeps the original pre-first-apply snapshot and owner set, but applies the configured MCP merge strategy to the current file. A laterrevertstill restores the original snapshot and may discard edits made after the first apply; inspect the resulting MCP config before relying on it. - For the shared
.vscode/mcp.jsondestination, include every owner recorded for that file (often Copilot and VS Code). Check both--agentsanddefault_agents; a recorded agent can be restored even if it is now disabled, but the selection must include it. - If the MCP config is a symlink, inspect and resolve it safely before retrying. AgentSync refuses to follow or replace symlinked MCP configs.
- If no journal exists from an earlier AgentSync version, the pre-apply content cannot be reconstructed. The config is left as-is; AgentSync does not delete servers by name or value.
--dry-rundoes not create or change MCP files or journal state.- For a project rooted exactly at
$HOME, the OS default local data directory is allowed there. If that home is a Git repository, ensure the platform’s default data directory is ignored so the private journal is not staged. An explicitAGENTSYNC_DATA_DIRmust be an absolute path outside the project root, including a home-directory project; for a narrower repository, set it to another external location.
The journal is outside the repository and snapshots the whole original MCP config, which may include credentials. It has no automatic expiry and remains until successful restore; clean does not remove it. See the MCP journal and restore guide for its location, retention, and full restore rules.
Quick checklist before opening an issue
Section titled “Quick checklist before opening an issue”Collect this output and paste it into the report:
which agentsyncagentsync --versionagentsync doctoragentsync statusagentsync apply --dry-runAlso note:
- Install method (npm/pnpm/yarn/bun global, one-off runner, GitHub release tarball, or
cargo install). - OS and shell.
- Whether
~/.cargo/binor another globalbinshadows the expected binary.
Related docs:
- Getting Started for install methods
- CLI Reference for flags such as
--project-root,--agents,--dry-run, and--no-gitignore - Gitignore Team Workflows for managed-destination policy
- Git Hook Automation for keeping links fresh after branch switches
- Windows Symlink Setup for native and WSL prerequisites