jdx/mise · error
present file has content
Error message
present file has content
What it means
This is a Rust `.expect()` panic, not a catchable error. It fires when a managed file is marked `ManagedState::Present` while building the privileged `WriteFile` action, but its `content` field is `None`. The codebase's invariant is that any file declared Present must carry the content to write; a None here means the file was constructed incoherently.
Solutions
- Set the `content` field whenever `state` is `ManagedState::Present` before invoking the apply path
- Validate the file entry at construction/deserialization time and reject Present-without-content early with a real error
- Switch the state to `ManagedState::Absent` if the file should only be removed, not written
Example fix
// before
ManagedFile { path, state: ManagedState::Present, content: None, .. }
// after
ManagedFile { path, state: ManagedState::Present, content: Some(expected_content), .. } Defensive patterns
Strategy: validation
Validate before calling
fn validate_managed_file(f: &ManagedFile) -> Result<()> {
if f.state == ManagedState::Present && f.content.is_none() {
return Err(anyhow!("file {} marked Present but has no content", f.path.display()));
}
Ok(())
} Type guard
fn has_content(f: &ManagedFile) -> bool {
f.state != ManagedState::Present || f.content.is_some()
} Prevention
- Always pair ManagedState::Present with Some(content) at construction
- Validate managed-file entries right after config deserialization
- Prefer Absent state when content is unknown
When it happens
Trigger: Calling the managed-file apply/plan path (src/system/managed_files.rs:673) with a `ManagedFile` whose `state` is `Present` but whose `content` was never set (constructed programmatically or deserialized from a config/partial state that omitted `content`).
Common situations: Hand-constructing a ManagedFile in a plugin or test; a config schema change that drops the `content` field; deserializing state from an older/other tool version that allowed Present without content.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- declaring bootstrap config is loaded
- explicit task name was just found
- matching group is present
- matching owner is present
- new config Arc is uniquely owned
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/5833d3104650fc11.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/managed_files.rs:673
}
fn operation(&self) -> Result<Option<PrivilegedAction>> {
match self.plan()?.action {
ResourceAction::Noop => return Ok(None),
ResourceAction::Unknown if self.state == ManagedState::Absent => bail!(
"refusing to remove directory {} as a file; declare it in [bootstrap.directories]",
self.path.display()
),
ResourceAction::Unknown => bail!(
"refusing to replace non-file path {}; set replace = true to allow replacement",
self.path.display()
),
_ => {}
}
Ok(Some(match self.state {
ManagedState::Present => PrivilegedAction::WriteFile {
path: self.path.clone(),
content: self.content.clone().expect("present file has content"),
owner: self.owner.clone(),
group: self.group.clone(),
mode: self.mode,
replace: self.replace,
},
ManagedState::Absent => PrivilegedAction::RemoveFile {
path: self.path.clone(),
},
}))
}
}
fn resolve_source_path(base: &Path, source: &str) -> PathBuf {
let source = if source.starts_with("~/") {
crate::file::replace_path(source)
} else {
PathBuf::from(source)
};View on GitHub (pinned to 533346cc37)