jdx/mise · error

[bootstrap.files]."{}": present files require source or cont

Error message

[bootstrap.files]."{}": present files require source or content

What it means

The (None, None, Present) arm of from_toml's match: a `[bootstrap.files]` entry with `state = "present"` (the default state) declared neither `source` nor `content`, so there is nothing to write (managed_files.rs:459-462). Present files need material; absent files (None,None,Absent) are the valid no-key form.

Source

Thrown at src/system/managed_files.rs:463

                )
            }
            (Some(source), None, ManagedState::Present) => {
                let source = Path::new(&source);
                let source = if source.is_absolute() {
                    source.to_path_buf()
                } else {
                    base.join(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()

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Add `content = "..."` with the inline file body, or `source = "path/to/file"` (absolute, or relative to the config file's directory) supplying the body
  2. If the file shouldn't be managed as present, set `state = "absent"` and keep no content keys
  3. Verify the key actually sits inside the right `[bootstrap.files."<path>"]` table (no stray blank line turning it into a new table)

Example fix

# before
[bootstrap.files."/etc/app.env"]
owner = "root"
mode = "0644"

# after
[bootstrap.files."/etc/app.env"]
owner = "root"
mode = "0644"
content = "KEY=value\n"
Defensive patterns

Strategy: validation

Validate before calling

for (path, f) in bootstrap_files(config) {
    if f.state.unwrap_or(Present) == Present {
        assert!(f.source.is_some() || f.content.is_some(),
            "{path}: present file needs source or content");
    }
}

Type guard

fn is_complete_file_entry(f: &ManagedFileTomlConfig) -> bool {
    matches!(f.state, None | Some(Present)) && f.source.is_none() && f.content.is_none() ^ true
        && (f.source.is_some() || f.content.is_some() || f.state == Some(Absent))
}

Prevention

When it happens

Trigger: `[bootstrap.files."/etc/app.env"]` with only owner/group/mode and no source/content; or an entry where state was flipped from "absent" to "present" without adding material. Note state defaults to present, so a bare entry with just metadata triggers this.

Common situations: Starting an entry as a metadata skeleton intending to add content later; deleting the content key while debugging templating; YAML/TOML indentation mistakes that detach the content key from its table so it's parsed as absent.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/28892a6d63b908a7. Report an issue: GitHub.