jdx/mise · error

aube lockfile must contain a mapping

Error message

aube lockfile must contain a mapping

What it means

Thrown by `AubeLock::from_yaml` when a mise.lock aube section parses as YAML but its top level is not a mapping (table). The lockfile graph must be a YAML map of package -> data; anything else (list, scalar) is rejected to prevent corrupt lock data being loaded.

Solutions

  1. Restore mise.lock from git (`git checkout -- mise.lock`)
  2. Fix the aube section so its top level is a mapping (key: value pairs)
  3. Regenerate the lockfile by deleting it and re-running the install/lock operation
  4. Avoid hand-editing mise.lock; let mise manage it

Example fix

# before (invalid: top-level sequence)
- node
- 22.0.0
# after (valid mapping)
node:
  version: 22.0.0
Defensive patterns

Strategy: try-catch

Validate before calling

# sanity check before use
yq -e 'tag == "!!map"' mise.lock >/dev/null || git checkout -- mise.lock

Try / catch

if let Err(e) = result {
    if e.to_string().contains("must contain a mapping") {
        // restore or regenerate mise.lock
    }
}

Prevention

When it happens

Trigger: mise.lock's aube graph section was hand-edited or corrupted so its top-level structure is a sequence or scalar instead of a mapping; a bad merge or truncation produced invalid YAML structure.

Common situations: Manual editing of mise.lock; merge conflict resolved incorrectly leaving a list at top level; accidental deletion of mapping keys.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/d47f029920d649f6. Report an issue: GitHub.

Appendix: source

Thrown at src/lockfile.rs:92

    pub graph: toml::Table,
    #[serde(skip)]
    pub graph_text: String,
    #[serde(skip)]
    pub project: Option<String>,
}

impl PartialEq for AubeLock {
    fn eq(&self, other: &Self) -> bool {
        self.graph == other.graph
    }
}
impl Eq for AubeLock {}

impl AubeLock {
    pub(crate) fn from_yaml(contents: &str) -> Result<Self> {
        let value: serde_yaml::Value = serde_yaml::from_str(contents)?;
        let toml::Value::Table(graph) = yaml_to_toml(value)? else {
            bail!("aube lockfile must contain a mapping");
        };
        Ok(Self {
            graph,
            graph_text: contents.to_owned(),
            project: None,
        })
    }

    pub(crate) fn to_yaml(&self) -> Result<String> {
        if !self.graph_text.is_empty() {
            return Ok(self.graph_text.clone());
        }
        let value = toml_to_yaml(toml::Value::Table(self.graph.clone()));
        Ok(serde_yaml::to_string(&value)?)
    }

    pub(crate) fn legacy_identity(&self) -> Result<String> {
        use sha2::{Digest, Sha256};

View on GitHub (pinned to 533346cc37)