Troubleshooting
Read the failed run before retrying a full update. A retry can update the CLI, sync repositories, or repeat external work. Earlier successful changes are not rolled back when a later task fails.
- Use the exact
dotfiles log --id … -vcommand printed after the failure. - Check its profile, platform, overlay, and requested tasks.
- Find the first failed or unmet task, not just dependents marked blocked.
- Fix that cause, preview a focused rerun, then apply it when ready.
Examples assume you are in the intended checkout with dotfiles on PATH.
If the launcher is uncertain, substitute an existing ./bin/dotfiles or
.\bin\dotfiles.exe. A wrapper may download/build even before showing help.
Find the symptom
Section titled “Find the symptom”| Problem | Go to |
|---|---|
| No usable CLI | Bootstrap, source build |
| Old version or a stalled upgrade | Self-update, legacy updater recovery |
| Selection or parsing error | Profile, configuration, overlay |
| Missing/skipped work | Task selection, elevation |
| Concurrent or failed repository run | Run lock, Git synchronization |
| Packages or tooling | Packages, Paru, agent packages, analyzers |
| Windows links | Symlinks |
| Settings not active | systemd, keyring, WSL |
| Removal left settings behind | Remove is not rollback |
Reading logs and partial results
Section titled “Reading logs and partial results”dotfiles log --listdotfiles log --task symlinks --verboseThe second command examines the newest run. For an older failure, add its
actual --id from history; IDs stay stable when new runs are added.
Read captured command diagnostics, not just a short task summary or an
“update available” notice. Failed-command output and nonempty stderr normally
appear without verbose; --verbose adds checks and other diagnostics.
Successful stdout is usually not retained, so --raw cannot recover it.
Restarted/elevated children have their own linked logs. If the parent only
reports a restart or delegation, inspect the child. unfinished means no finish
record exists; that can also describe a process still running.
If logging failed, check free space and permissions at the log location. Sanitize private paths, configuration, and external tool output before sharing logs.
The wrapper cannot find or download the binary
Section titled “The wrapper cannot find or download the binary”| Error | Check |
|---|---|
| Cannot resolve a release repository | The checkout’s GitHub origin, or an explicit DOTFILES_RELEASE_REPO=owner/repo |
| Latest release/download unavailable | DNS, proxy, HTTPS access, rate limits, and whether that publisher has releases |
| Unsupported architecture | Published assets support Linux x86-64/AArch64 and Windows x86-64 |
| Missing checksum or checksum mismatch | The matching release asset/checksum file; do not execute the failed download |
| Provenance verification failed | gh, authentication, network access, and the verification error |
| Binary cannot execute | OS/architecture, Linux executable permission, and local file-access policy |
Forks do not silently fall back to this project’s binaries. A fork without releases needs a deliberate publisher override or a source build; the setup guide shows both choices.
Bootstrap warns and continues if gh is absent. If gh is present,
verification failure blocks it; self-update also refuses unverifiable updates.
Do not bypass checksums or set DOTFILES_SKIP_ATTESTATION=1 as a routine fix.
See Build provenance verification.
Wrappers clean failed downloads. Do not delete the checkout or all of bin/.
If one stale binary must be moved aside, first confirm no run is using it.
The binary never self-updates
Section titled “The binary never self-updates”Check these before replacing anything:
- Only update/remove trigger CLI self-update; help, version, list, log, and check do not.
- The binary must be an eligible release build, have an embedded publisher,
and run from the selected checkout’s
bin/. DOTFILES_SKIP_SELF_UPDATE=1disables the check.- Dry-run reports an available update but does not install it.
- A fresh cache can delay another lookup for up to ten minutes. Linux cache entries also need to match the current boot.
- A failed release lookup leaves the existing binary usable; a failed download or verification is a separate error.
Changing origin or DOTFILES_RELEASE_REPO does not change an existing
binary’s embedded self-update publisher.
For authentication, release discovery prefers nonempty GH_TOKEN, then
GITHUB_TOKEN, then an unattended saved GitHub CLI login. An expired explicit
token can override a working login; correct or unset it. Denied credentials
are not silently retried anonymously.
Anonymous requests share a lower GitHub quota with other users of the same
public IP. Respect a reported retry deadline instead of repeatedly retrying.
Normal saved authentication can be set up with gh auth login --hostname github.com.
For Linux keyring-only credentials, follow the
automatic verification authentication guidance.
Legacy updater recovery
Section titled “Legacy updater recovery”These recovery steps apply to an installed binary that rejects the current
vYYYY.MM.DD-N release names or blocks on a desktop-keyring dialog during
automatic verification. They are not normal setup steps: the current updater
supports those release names and disables interactive keyring access.
For an unrecognized release name, preserve the affected executable and bootstrap again with the checkout’s wrapper. Confirm that no run is using it before moving it. Never bypass verification to force an upgrade.
For a hidden credential dialog, including under WSL, provide authentication through the supported credential sources. A source build avoids the installed updater. To temporarily disable a release check instead, use the lifecycle control; it does not disable the rest of update.
Cargo build fails
Section titled “Cargo build fails”Use the build prerequisites and read the first compiler or linker error, not just the wrapper’s final status.
Use the source-build command to build and print
a version without applying configuration. Do not copy an arbitrary old
executable into bin/ to hide a build failure.
No profile can be selected
Section titled “No profile can be selected”dotfiles list --profile basegit config --local --get dotfiles.profileUse exactly base or desktop. Priority is CLI, nonempty DOTFILES_PROFILE,
saved Git setting, then interactive prompt. A bad environment value does not
fall back to the saved setting; surrounding whitespace is not trimmed.
list never prompts for a profile. Update/remove/check also need an existing
selection in unattended or JSON Lines mode, with non-terminal stdin, or with
any present CI variable. An explicit profile overrides the saved choice
without updating it. See Profile selection.
Configuration does not parse
Section titled “Configuration does not parse”Start with the filename and complete diagnostic. Common causes are a missing required file, malformed TOML, wrong value type, unsupported key/category, conflicting targets, unsafe path, or missing source.
Configuration loads before task filtering. --only symlinks cannot bypass
malformed package configuration. Inactive categories are not a safe place to
leave invalid definitions.
Use Configuration validation to interpret the
finding and CLI validation to recheck it.
check does not repair files, and config-diagnostics fails on warning-severity
diagnostics too.
An overlay appears to be ignored
Section titled “An overlay appears to be ignored”For a sibling overlay called dotfiles-private, inspect it from the main
checkout:
git config --local --get dotfiles.overlaydotfiles list --overlay ../dotfiles-privateThen check:
- The selected path is the overlay root, not its
conf/directory. - A higher-priority flag or environment value is not overriding the saved path.
- Its sections match the active categories.
- Overrides match the resource’s identity, not just a table name or position. Inactive overlay entries do not replace active public entries.
- Script declarations live in overlay
conf/scripts.toml, with script paths relative to that overlay root.
Missing optional files add nothing, so a wrong path can look like an empty overlay. See Private overlays for selection, persistence, and linked-worktree requirements.
A task does not run
Section titled “A task does not run”Inspect selection before executing more work:
dotfiles listdotfiles list --graph update --only systemd| What you see | What to check |
|---|---|
| Unknown selector | Use an exact selector/full label from list, not a substring or package ID |
| Missing from the command | Look under the correct update/remove/check group; try list --all |
filtered or skipped in the graph | Check both --only and --skip |
| Omitted prerequisite warning | Decide whether to include --with-deps |
| No normal result row | The task may be current or inapplicable; inspect verbose output/logs |
requires … or blocked | Fix the named prerequisite first |
| Missing capability/tool | Provide that prerequisite deliberately |
| No active entries | Check the profile/category selection |
For a focused preview:
dotfiles update --only systemd --dry-run --verboseAdd --with-deps only after reviewing its graph: it can bring in package
installation, AUR setup, links, and permissions. It is not a narrower retry.
Another run holds the repository lock
Section titled “Another run holds the repository lock”Update, remove, and check share a lock, including previews. Linked worktrees use the same common Git directory. The error identifies the lock and, when available, the owner PID, command, and start time.
Wait for the owner or inspect it. list and log remain usable.
Do not delete the lock file to force concurrent runs. The process holds
the lock; leftover owner text alone does not keep it locked.
For a stuck run, follow the interrupt procedure. After force quit, check for surviving child installers before retrying.
Repository update fails
Section titled “Repository update fails”Inspect the affected main or overlay checkout:
git status --shortgit branch -vvgit remote -vCheck remote URLs for credentials before sharing the output.
| Cause | Recovery |
|---|---|
| Tracked local changes | Preserve and resolve them; synchronization skips a dirty checkout |
| Detached HEAD | Repository update is inapplicable; choose the intended branch if appropriate |
| Missing upstream | Configure the intended upstream or deliberately keep current content |
| Local/diverged commits | Reconcile the branch yourself; dotfiles does not reset or rebase |
| Authentication/network failure | Inspect the failed Git command and credentials |
| Fast-forward merge failure | Protect local content, including untracked files that collide |
Untracked files do not fail the readiness check, but can still prevent a merge. Main and overlay updates are not one transaction.
Use --no-repo-update when you deliberately want to apply the current checkout.
It does not discard changes or suppress other network activity.
“Repository synced · restarting to load configuration” is normal: the child
reloads configuration while the parent retains the lock.
A task was skipped because elevation was unavailable
Section titled “A task was skipped because elevation was unavailable”| Reason | Meaning |
|---|---|
elevation declined | Windows UAC consent was dismissed |
elevation unavailable in a non-interactive session | No supported prompt path |
sudo credentials unavailable | Linux sudo was missing, denied, or could not be primed |
sudo credentials unavailable in a non-interactive session | No usable cached/passwordless authorization |
requires <task> | A blocking prerequisite was left unmet |
ran in elevated session | Work was delegated; inspect the child log |
Windows delegates only selected tasks. Linux primes sudo credentials and uses
sudo for privileged commands; neither requires elevating the whole workflow.
Independent tasks can continue, while --fail-on-skip or CI fails unmet work.
Resolve authorization for the named scope, then retry. Do not bypass policy or create passwordless sudo rules just to clear a failure. Winget installer refusals are different: they count as failed package items, not only strict-mode skips.
Packages do not install
Section titled “Packages do not install”Identify the task: packages, paru, or aur-packages. Native Linux packages
need pacman; there is no apt/dnf provider. Windows uses winget. AUR packages
need Arch and a healthy Paru.
dotfiles update --only packages --dry-run --verboseA failed installed-package query is not an empty machine. Fix the provider failure before retrying. Check the exact configured ID, active category, and authorization reason.
--only packages does not include AUR entries. --only aur-packages assumes
its omitted prerequisites are satisfied unless you add --with-deps.
Arch package recipe or pin failures belong in
Arch package recipes.
Applying missing Arch packages runs pacman -Syu --needed --noconfirm and can
upgrade the whole system. Do not use apply as a harmless diagnostic.
For Windows scope, UAC, and policy failures, see Windows packages.
Paru bootstrap reports an incomplete Rust/Cargo prerequisite
Section titled “Paru bootstrap reports an incomplete Rust/Cargo prerequisite”These read-only probes separate a missing package, broken executable, and incomplete build toolchain:
pacman -Q paru/usr/bin/paru --versioncargo --versionParu bootstrap needs Git, makepkg, sudo, and a working Cargo. A rustup proxy
without a selected toolchain can exist on PATH but fail cargo --version.
Provision the complete Arch build prerequisites using the distribution’s full-upgrade workflow, or configure rustup if that is your intended toolchain manager. Do not repair this through partial library upgrades.
A missing libalpm.so.* usually means the helper needs rebuilding against the
current system libraries. Dotfiles checks the installed package and canonical
executable, rebuilds a broken helper, and validates it again. When provisioning
Arch in a chroot, inspect the target system; repairing only the live ISO does
not repair the installed system.
Agent package update does not run or fails
Section titled “Agent package update does not run or fails”dotfiles update --only agent-packages --dry-run --verboseConfirm that the linked fragments exist, APM is available when native planning
needs it, and the named authentication requirement is met. Review dependency
expansion before adding --with-deps.
If the generated manifest needs changing, preview reports that write and the
delegated update instead of planning against stale input. With a current
manifest it delegates to apm update -g --dry-run.
Apply updates dependencies when their declared version rules allow it, then installs local content and repairs deployments even when no version changed. Edit tracked fragments/plugins, not generated manifests or installed plugin copies. See Agent configuration.
Optional analyzers are not running
Section titled “Optional analyzers are not running”Read the named missing tool or module in the check result, then use the
analyzer prerequisites to resolve it.
Reopen the shell if PATH changed and retry. Strict runs (--fail-on-skip or CI)
fail on unmet skips; filtering a check out is not evidence it passed.
A symlink cannot be created on Windows
Section titled “A symlink cannot be created on Windows”Check permission, target conflicts, and source checkout separately:
- File links need Developer Mode or suitable elevation. Directory links can fall back to junctions.
- Regular files and empty directories can be replaced without backup; nonempty directories are not recursively removed.
- A Git symlink checked out as ordinary text must be repaired in the source checkout. Elevating the home-link task does not fix it.
See Developer Mode and symlinks for inspection commands and a preview including Developer Mode.
systemd changes are not visible
Section titled “systemd changes are not visible”First check whether the configured unit is user or system scope. Bare unit names default to user scope. Substitute the actual unit name:
systemctl --user status example.service --no-pagerjournalctl --user -u example.service -n 50 --no-pagerFor a system unit, omit --user. Check that packages, linked unit files, and
executable scripts exist. Ordering after those tasks does not mean every
unrelated failure in them blocks the service task.
Without a user manager, including during Arch chroot provisioning, dotfiles enables user units offline rather than starting them. Log in normally to test runtime behavior. In WSL, systemd must be running or degraded for unit configuration to proceed.
For extension installation deferred during Arch chroot provisioning, inspect:
journalctl --user -u dotfiles-first-login.service -n 50 --no-pagerDo not restart the whole desktop as the first diagnostic. See Arch desktop for session/service context.
GNOME Keyring does not unlock at login
Section titled “GNOME Keyring does not unlock at login”The PAM fragments are selected for Arch + desktop. Preview them with:
dotfiles update --only system-files --dry-run --verboseThis task can cover other selected system files too. Review before applying; do not hand-edit unrelated PAM rules.
After an authorized apply, save work, fully log out of the TTY session, and log back in. Restarting Hyprland alone does not repeat PAM login. Inspect the keyring:
busctl --user get-property \ org.freedesktop.secrets \ /org/freedesktop/secrets/collection/login \ org.freedesktop.Secret.Collection Lockedb false means unlocked. If the keyring password differs from the login
password, change it through the keyring’s normal password management.
Passwordless autologin supplies no password for PAM to unlock it.
WSL settings did not change
Section titled “WSL settings did not change”Run the Linux CLI inside the distribution. Confirm system-files applied
the WSL-selected settings; a dry run does not change /etc/wsl.conf.
After saving all WSL work, restart from Windows:
wsl --shutdownThis terminates all running distributions and their processes, not just the current one. Reopen the intended distribution afterward. See WSL setup.
Remove did not restore machine defaults
Section titled “Remove did not restore machine defaults”This is expected. Remove copies selected home-link content into real files, removes matching managed hooks/launchers, and runs active overlay removal scripts. It does not restore a machine snapshot or uninstall everything that update can configure.
Use the original profile and overlay. Keep the checkout until copying succeeds, and remember that copies contain the current source rather than your pre-install files. See Remove for what remains.