jdx/mise · error
[bootstrap.files]."{}": absent files must not declare source
Error message
[bootstrap.files]."{}": absent files must not declare source or content What it means
Raised by ManagedFileRequest::from_toml when a [bootstrap.files] entry declares state="absent" but also supplies `source` or `content`. Deletion only needs the path; providing a body for a file the library is asked to remove is contradictory, so the entry is rejected at parse time.
Source
Thrown at src/system/managed_files.rs:557
)
}
(Some(source), None, ManagedState::Present) => {
let source = resolve_source_path(base, &source);
Some(fs::read_to_string(&source).wrap_err_with(|| {
format!(
"[bootstrap.files].\"{}\": failed to read source {}",
path.display(),
source.display()
)
})?)
}
(None, Some(content), ManagedState::Present) => Some(content),
(None, None, ManagedState::Present) => bail!(
"[bootstrap.files].\"{}\": present files require source or content",
path.display()
),
(None, None, ManagedState::Absent) => None,
(_, _, ManagedState::Absent) => bail!(
"[bootstrap.files].\"{}\": absent files must not declare source or content",
path.display()
),
};
if config.template {
let rendered = content
.as_deref()
.map(|content| secrets.render(root_config, content, base, &path))
.transpose()
.wrap_err_with(|| {
format!(
"[bootstrap.files].\"{}\": failed to render template",
path.display()
)
})?;
content = rendered;
}
Ok(Self {View on GitHub (pinned to afd2eddd3a)
Solutions
- Remove the `source` and `content` keys from the absent-state entry, keeping only path and state.
- If you actually want the file to exist with that body, set state = "present" instead.
- Re-run bootstrap to confirm the config parses.
Example fix
# before [[bootstrap.files]] path = "/etc/legacy.conf" content = "old settings" state = "absent" # after [[bootstrap.files]] path = "/etc/legacy.conf" state = "absent"
Defensive patterns
Strategy: validation
Validate before calling
fn validate_file_entry(entry: &ManagedFileTomlConfig) -> Result<(), String> {
if entry.state == ManagedState::Absent && (entry.source.is_some() || entry.content.is_some()) {
return Err("absent files must not declare source or content".into());
}
Ok(())
} Type guard
fn absent_with_body(entry: &ManagedFileTomlConfig) -> bool {
entry.state == ManagedState::Absent && (entry.source.is_some() || entry.content.is_some())
} Prevention
- Absent entries should contain only path, state (and removal flags) — no body keys.
- When duplicating a present entry to make an absent one, strip `source`/`content`.
- Lint generated configs to reject body keys on absent entries.
When it happens
Trigger: Parsing a [bootstrap.files."<path>"] TOML entry with state = "absent" where `source` and/or `content` is set — the (_, _, ManagedState::Absent) catch-all arm after the (None, None, Absent) case.
Common situations: Duplicating an existing present-file block and changing only state to "absent" without removing the body keys; a cleanup entry written by copying a template config that always includes `content`; bulk-generating entries where absent/present is data-driven and body keys leak into absent ones.
Related errors
- [bootstrap.files]."{}": source and content are mutually excl
- [bootstrap.files]."{}": present files require source or cont
- [bootstrap.directories]."{}": recursive is only valid with s
- managed path '{}' notifies unconfigured bootstrap service '{
- managed path '{}' notifies unconfigured bootstrap service '{
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/d67e8d06c6c72b4a.
Report an issue: GitHub.