jdx/mise · error
dotfiles: {} is still tracked
Error message
dotfiles: {} is still tracked What it means
After attempting to remove tracking (rewinding config and reloading TrackedSet), untrack verifies the path is genuinely gone from the tracked set. If an entry still exists for the exact path, the untrack did not take effect and the command fails rather than leaving inconsistent state.
Source
Thrown at src/cli/dotfiles/untrack.rs:169
table.insert("enabled", Value::Boolean(toml_edit::Formatted::new(false)));
doc["dotfiles"][&key] = Item::Value(Value::InlineTable(table));
file::write(&local, doc.to_string())?;
info!(
"dotfiles: {key} is also declared in {}; switched off in {}",
entry
.declared_in
.as_deref()
.map(display_path)
.unwrap_or_else(|| "another layer".into()),
display_path(&local)
);
config = Config::reset().await?;
tracked = TrackedSet::from_config(&config)?;
if tracked
.entry_for(&path)
.is_some_and(|entry| entry.path == path)
{
bail!("dotfiles: {} is still tracked", display_path(&path));
}
}
}
// A capture command may invoke untrack itself. Its parent holds the
// operation lock and records the new enrollment in its outcome; do
// not wait on that parent or commit a competing boundary here.
if std::env::var_os(crate::system::history::scope::ENV_VAR).is_some()
|| crate::system::history::scope::is_active()
{
info!(
"dotfiles: tracking stopped; the enclosing operation will record the change. Live files and earlier committed versions remain"
);
return Ok(());
}
let store = crate::system::history::checkpoint::Store::open()?;
let mut draft = crate::system::history::checkpoint::Draft::new(
crate::system::history::store::Trigger::Save,
);View on GitHub (pinned to afd2eddd3a)
Solutions
- Re-run `mise dotfiles untrack` (transient reload race resolves itself)
- Inspect all config layers (`~/.config/mise/config.toml`, project config, config.local.toml) for a duplicate declaration of the target and remove the extra one
- Check for other running mise dotfiles processes that may re-enroll the path
Defensive patterns
Strategy: try-catch
Validate before calling
# no tracked entry should exist for the path before untrack ! mise dotfiles ls | grep -Fx -- "$path" || echo "already declared elsewhere"
Try / catch
mise dotfiles untrack "$path" || {
sleep 1
mise dotfiles untrack "$path" # retry once; config reload race
} Prevention
- Avoid running concurrent mise dotfiles commands
- Keep target declarations in one config layer to prevent duplicates
- After failure, grep all mise config files for the target
When it happens
Trigger: `mise dotfiles untrack` re-reads config (Config::reset) and finds entry_for(path) still matching the exact path — the removal from config did not persist or a parent/sibling declaration still tracks the exact path.
Common situations: Concurrent dotfiles command rewrote the config; the path was declared in multiple config layers (local + global); a capture command re-enrolled it during the operation.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- [dotfiles]."{}": source does not exist: {}
- [dotfiles]."{}": mode symlink-each requires a directory sour
- [dotfiles]."{}": target is not a safe OCI path
- {raw}: multiple [dotfiles] edit entries match; choose one of
- history is disabled (history.enabled = false)
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/7140d021071bbc52.
Report an issue: GitHub.