jdx/mise · error
[bootstrap.directories]."{}": recursive is only valid with s
Error message
[bootstrap.directories]."{}": recursive is only valid with state = "absent" What it means
Raised by ManagedDirectoryRequest::from_toml for [bootstrap.directories] entries. `recursive = true` (recursive removal of the tree) is only meaningful when state = "absent"; combining it with state = "present" is contradictory — creation has no meaningful notion of recursion via this flag — so the entry is rejected at parse time.
Source
Thrown at src/system/managed_files.rs:642
crate::file::replace_path(source)
} else {
PathBuf::from(source)
};
if source.is_absolute() {
source
} else {
base.join(source)
}
}
impl ManagedDirectoryRequest {
fn from_toml(
path: PathBuf,
config: ManagedDirectoryTomlConfig,
origin: ResourceOrigin,
) -> Result<Self> {
if config.state == ManagedState::Present && config.recursive {
bail!(
"[bootstrap.directories].\"{}\": recursive is only valid with state = \"absent\"",
path.display()
);
}
Ok(Self {
path,
owner: nonempty("owner", config.owner)?,
group: nonempty("group", config.group)?,
mode: parse_mode(config.mode.as_deref(), 0o755)?,
state: config.state,
recursive: config.recursive,
replace: config.replace,
notify: config.notify,
origin,
inspection: None,
})
}
View on GitHub (pinned to afd2eddd3a)
Solutions
- Remove `recursive = true` from the present-state directory entry (creating a directory already creates parents).
- If you intended recursive removal of the tree, set state = "absent" and keep recursive = true.
- Re-run bootstrap to confirm the config parses.
Example fix
# before [[bootstrap.directories]] path = "/var/lib/myapp/cache" state = "present" recursive = true # after [[bootstrap.directories]] path = "/var/lib/myapp/cache" state = "present"
Defensive patterns
Strategy: validation
Validate before calling
fn validate_directory_entry(entry: &ManagedDirectoryTomlConfig) -> Result<(), String> {
if entry.state == ManagedState::Present && entry.recursive {
return Err("recursive is only valid with state = \"absent\"".into());
}
Ok(())
} Type guard
fn invalid_recursive(entry: &ManagedDirectoryTomlConfig) -> bool {
entry.state == ManagedState::Present && entry.recursive
} Prevention
- Use `recursive = true` only on state = "absent" directory entries for tree removal.
- Directory creation already creates parents; do not add recursive for that purpose.
- Flip state flags and body flags together when converting entries between present/absent.
When it happens
Trigger: Parsing a [bootstrap.directories."<path>"] TOML entry where `recursive = true` AND state = "present" (or present is the default state).
Common situations: Copying an absent-removal entry and flipping state to "present" without removing `recursive`; assuming `recursive = true` creates parent directories and setting it on a create entry; bulk-generating entries where the flag leaks across entries.
Related errors
- [bootstrap.files]."{}": source and content are mutually excl
- [bootstrap.files]."{}": present files require source or cont
- [bootstrap.files]."{}": absent files must not declare source
- 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/9db22ad810fc4432.
Report an issue: GitHub.