Troubleshooting - Ziad0dev/dots GitHub Wiki
Grouped by where it breaks. Each entry is symptom → cause → fix.
The flake is read from git. Untracked files don't exist and unstaged new files are invisible. git add -A, then retry. The pre-commit hook catches flake.nix references to untracked modules; it can't catch everything.
--show-trace prints outermost frames first. The frames at the top (system.build.toplevel, head, modules.nix:…) are noise; the real message — often a Failed assertions: block — is at the bottom.
nh os build --show-trace 2>&1 | tail -40The same key appears twice in one file — a plain duplicate, not a module merge conflict. Search the file for the attribute path.
nixpkgs follows chaotic/nixpkgs. Update chaotic: nh os switch -U chaotic.
Happened once when chaotic-nyx's overlay re-imported nixpkgs without the (newly deferred) config — upstream issue chaotic-cx/nyx#2276, fixed in #2304. If it recurs after an update: nh os switch -U chaotic first; as a temporary bridge, NIXPKGS_ALLOW_UNFREE=1 nh os switch. The same variable is how you get unfree packages in nix shell nixpkgs#…, which never sees system config.
output … is not allowed to refer to … linux-…-dev while building the NVIDIA open module.
The CachyOS kernel compresses modules, so they install as .ko.zst, and nixpkgs' nuke-refs pass only looks at .ko — a reference to the kernel's dev output survives inside nvidia-modeset.ko.zst. It only bites when the driver is built locally (a cache miss on chaotic's cache).
The fix was lib/nvidia-zstd-refs.nix, removed in Sep 2026 once the unpatched driver built clean; the host is back to package = pkgs.nvidia_cachyos-bore;. If the error returns, restore it from history (git log --diff-filter=D -- lib/nvidia-zstd-refs.nix) and wrap the package with it again. Its postFixup decompresses each .ko.zst, strips references, recompresses. Things to know if you bring it back:
- It's a function, not a module — keep it out of
modules/and out ofimports, or NixOS calls it with module arguments and fails with "unexpected argument". - It adds
nukeReferencesexplicitly; theopenderivation doesn't inherit it from nvidia-x11. - If the
opendrv hash doesn't change after editing the fix, the override never reached the derivation: checknix eval ~/dots#nixosConfigurations.nixos.config.hardware.nvidia.package.open.drvPath. - Don't "fix" it by pinning an older driver branch — the override is version-independent.
sign-file SSL warnings and "missing System.map. Skipping depmod." in that build log are normal.
Not from this repo or any input's own .nix files. They're emitted once when chaotic's CachyOS kernel package set is constructed. Harmless.
It runs shellcheck with warnings as errors. Sourcing a file by variable trips SC1090 — put the source in its own function with # shellcheck source=/dev/null above it (see scripts/themectl.sh). It also runs with set -euo pipefail: using a variable before it's assigned is fatal at runtime.
Already absorbed on the current pin — useful when reading older configs or upstream examples:
| Old | Now |
|---|---|
services.locate.localuser |
removed (plocate has no per-user mode) — hard assertion |
virtualisation.libvirtd.qemu.ovmf |
removed — hard assertion; OVMF is available by default |
programs.git.extraConfig |
programs.git.settings |
home.pointerCursor |
needs enable = true
|
poppler_utils |
poppler-utils |
services.ollama.acceleration / models
|
package = pkgs.ollama-vulkan / modelsDir
|
services.llama-cpp.extraFlags |
settings (keys are llama-server long flags) |
Check for packages whose defaults pull everything: tesseract without enableLanguages pulls ~1 GiB of language data (the desktop pins five languages).
A .backup from an earlier collision is in the way. Delete the stale .backup and switch again. For files an app keeps rewriting (e.g. mimeapps.list), xdg.configFile."…".force = true — which means home-manager owns the file outright, so every association you want must be declared.
The same package reached home-manager-path twice — typically listed in home.packages and installed by an HM module (programs.foo, nixcord, …). Remove the home.packages entry.
Check who owns the path: readlink ~/.config/<app>. If it isn't a link into the repo, a home-manager module (or an app) owns it. One owner per path.
The config is Lua. Dispatchers are namespaced (hl.dsp.*) and legacy strings exit 0 while doing nothing — the pre-commit hook rejects them under config/. Runtime monitor changes don't go through hyprctl keyword either: edit hyprland.lua and hyprctl reload. To leave the session from a shell: loginctl terminate-session $XDG_SESSION_ID.
graphical-session.target isn't active. The hyprland.start handler starts hyprland-session.target, which binds it. Check systemctl --user status hyprland-session.target; if the handler failed, the environment import line in hyprland.lua is the first suspect.
Check in this order:
-
Persistent HDR. DP-1's profile pins 10-bit +
cm = "hdr", which keeps the colour-management pipeline running every frame on the desktop. Removebitdepth,cmand the luminance keys from the profile when you're not watching HDR, and pincm = "srgb"— left on auto it picks a wide-gamut preset and sRGB content looks washed out. -
Software cursors.
hyprctl monitors | grep hardwareCursorsInUseshould say true on every output. On NVIDIA, the working combination isno_hardware_cursors = false+use_cpu_buffer = true(what's committed). - Blur and animation cost scale with resolution × refresh; at 1440p240 blur passes are expensive.
- Known upstream issues with the same signature: hyprwm discussion #11411, issues #7156 and #9471.
Was sched_ext: scx_lavd stalled media and browser threads (sched_ext: BPF scheduler "lavd_…" disabled (runnable task stall) in the journal) after a kernel bump outpaced scx-scheds. That's why services.scx.enable = false in modules/gaming.nix. If you re-enable it, keep sudo systemctl stop scx as the escape hatch — stopping the unit hands scheduling back to the kernel immediately, no reboot.
Nix wrappers rename the process: dunst runs as .dunst-wrapped, awww-daemon as .awww-daemon-wr (15-char comm truncation). Drop -x, or ask the program itself (awww query).
Something holds an org.freedesktop.ScreenSaver inhibit and keeps resetting hypridle's timer — Electron apps do it for autoplaying media (animated emoji count). Watch journalctl --user -u hypridle -f while idle, and check the bar's idle toggle hasn't simply stopped hypridle.
SDL picks Wayland because the desktop profile exports SDL_VIDEODRIVER=wayland, and SDL2's Wayland backend can't capture the mouse. home/flatpak.nix overrides SDL_VIDEODRIVER=x11 for it. Don't also set --nosocket=wayland — then SDL finds no Wayland socket and the client aborts (error 0x80F10000).
The NVIDIA GL extension is per driver version. Log out and back in (flatpak-nvidia-gl installs the matching one), or systemctl --user restart flatpak-nvidia-gl. Check with flatpak list --runtime | string match -e nvidia against cat /sys/module/nvidia/version. If Flathub hasn't published the new version yet, the install fails quietly and flatpaks stay on software GL until it does.
nix-flatpak uninstalls user apps that aren't declared. Add it to packages in home/flatpak.nix.
Waydroid's hardware rendering needs Mesa; the proprietary NVIDIA driver can't provide it, so Android has to render with SwiftShader. After sudo waydroid init, add to /var/lib/waydroid/waydroid.cfg under [properties]:
ro.hardware.gralloc=default
ro.hardware.egl=swiftshader
then sudo waydroid upgrade --offline and sudo systemctl restart waydroid-container. Expect it to be CPU-bound: fine for apps, not for games.
In order of likelihood:
-
metadata.desktopmust containQtVersion=6. Without it SDDM 0.21 looks for the Qt 5 greeter binary, which nixpkgs doesn't ship, and falls back — right after logging that it loadedtheme.conf, so that line proves nothing. -
services.displayManager.sddm.themeis the theme directory (alwaysdots, forced by the module). The palette isdots.sddm.theme. Setting the former to a palette name gets "theme doesn't exist". - Colours don't follow themectl: the greeter reads
/var/lib/dots-theme/sddm.jsonoverfile://, which Qt 6 blocks unlessQML_XHR_ALLOW_FILE_READ=1is inGreeterEnvironment(the module sets it whenlive = true). Setting it on the display-manager unit doesn't reach the greeter.
Cheap checks:
grep QtVersion /run/current-system/sw/share/sddm/themes/dots/metadata.desktop
cat /etc/sddm.conf.d/00-nixos.conf # there is no /etc/sddm.conf
sudo systemctl restart display-manager # the only full testjournalctl -b shows the current boot only — after a switch without a restart you're re-reading the old failure. Check timestamps.
Every unit that uses an external drive should have unitConfig.RequiresMountsFor. Drives are nofail + automount, so a missing drive doesn't block boot — the dependent service just waits or fails. dots-mounts lists unhealthy mounts. exFAT has no permissions: if a service can't write, the fix is the mount's uid/gid/umask options, not chmod.
- The GGUF isn't world-readable — the units run as
DynamicUser. - The model file is missing from
/var/lib/dots/models. - Another unit stopped when you started this one: expected, they
Conflict.
journalctl -u llama-coder -e.
They live in the wg namespace. Check systemctl status wg wg-dns qbittorrent, that /etc/wireguard/mullvad.conf exists, and that you're coming from the tailnet (LAN is dropped by design) or from the host via http://192.168.15.1:8081.
nh's GC runs with --keep-since 4d and reaps direnv GC roots older than that. nh ≥ 4.4 has --keep-one to keep one root per direnv project regardless of age — add it to programs.nh.clean.extraArgs in modules/dev.nix.
Packaged script — git add -A && update.
A template references a name that isn't a palette key and passed through unsubstituted; themectl warns unsubstituted tokens remain in …. A key missing from colors.sh no longer half-applies: themectl set refuses up front with theme '<name>' is missing palette keys: … and renders nothing. See Theming.
Things in the repo today that are wrong or brittle, not yet fixed:
| Where | Issue |
|---|---|
config/yazi/keymap.toml |
g d jumps to ~/dots, not dots.repoPath (a static TOML file can't read the option) |
flake.nix → hyprland-preview-share-picker
|
Tracks the upstream branch drop-hyprland-rs (master still needs hyprland-rs). If upstream deletes the branch before merging, nix flake update fails on this input: pin rev= to the locked commit, or move to master once it no longer uses hyprland-rs |
Source: docs/troubleshooting.md