jdx/mise · error
destination variants require an explicit source unless the…
Error message
destination variants require an explicit source unless the entry key is a relative source path
What it means
This error comes from `logical_source_path` in the dotfiles system. When a `[dotfiles]` entry overrides destination targets via `variants` but omits an explicit `source`, the entry key itself is treated as the source path. That only works if the key is a relative source path; an absolute key (after `~/` expansion) cannot be reinterpreted as a source, so the library refuses it.
Solutions
- Add an explicit `source = "relative/path"` to the entry table
- Change the entry key to a relative source path (e.g. `"dotfiles/gitconfig" = { variants = [...] }`) so the source can be implied
- Remove the `variants` block if per-destination targets are not needed
Example fix
// before
"~/.zshrc" = { variants = [ { target = "~/.zshrc" }, { target = "~/.config/zsh/rc" } ] }
// after
"~/.zshrc" = { source = "dotfiles/zshrc", variants = [ { target = "~/.zshrc" }, { target = "~/.config/zsh/rc" } ] } Defensive patterns
Strategy: validation
Validate before calling
function hasExplicitSource(entry) {
return typeof entry === 'string' || (entry && typeof entry.source === 'string' && entry.source.length > 0);
}
// before relying on implied source: if (entry.variants && !hasExplicitSource(entry) && isAbsolute(entryKey)) throw ... Type guard
const isRelativeSourceKey = (key: string) => !key.startsWith('/') && !key.startsWith('~') && !/^[A-Za-z]:[\\/]/.test(key); Prevention
- Always set an explicit `source` when using `variants`
- Keep entry keys relative (source-style) or always pair absolute keys with `source`
When it happens
Trigger: Declaring a dotfile entry whose key is an absolute path (e.g. `"~/.gitconfig"`) or `/absolute/path`, with `variants` that set per-destination targets, and no `source` field in the entry table.
Common situations: Users copy a dotfile entry that previously had `source = "dotfiles/gitconfig"`, delete the source field while adding a `variants` block to target multiple machines, or write the key as an absolute destination path assuming the source is inferred from somewhere else.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- an implied source entry key must be relative
- dotfile target must be absolute or start with ~/
- path " " must be absolute or start with ~/, ignoring entry
- agent ' ' `queue_directories` entry ' ' must be an absolute…
- an implied source entry key must not be empty
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/909c5e41cd76a27a.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/files.rs:247
} else {
None
};
if variants.is_empty() && resolve_target_arg(target).is_relative() {
bail!("target must be absolute or start with ~/");
}
for variant in variants {
let destination = variant.target.as_deref().unwrap_or(target);
if !variant_target_is_absolute(destination) {
bail!("variant target must be absolute or start with ~/");
}
}
Ok(implied_source)
}
fn logical_source_path(key: &str) -> Result<PathBuf> {
let path = file::replace_path(key);
if !path.is_relative() {
bail!(
"destination variants require an explicit source unless the entry key is a relative source path"
);
}
let mut relative = PathBuf::new();
for component in path.components() {
match component {
std::path::Component::Normal(component) => relative.push(component),
std::path::Component::CurDir => {}
std::path::Component::ParentDir => {
bail!("an implied source entry key must not contain '..'");
}
std::path::Component::RootDir | std::path::Component::Prefix(_) => {
bail!("an implied source entry key must be relative");
}
}
}
if relative.as_os_str().is_empty() {
bail!("an implied source entry key must not be empty");View on GitHub (pinned to 533346cc37)