wasmerio/wasmer · error

could not parse YAML semantically: {e}

Error message

could not parse YAML semantically: {e}

What it means

try_format_preserving_edit performs a second, semantic parse with serde_yaml so it can detect which keys changed (yaml_edit's node text can't be reparsed because block values are only dedented on the first line). If the syntax was valid to yaml_edit but serde_yaml rejects the value model (rare deserialization/type incompatibilities) this error is thrown.

Source

Thrown at lib/cli/src/utils/yaml.rs:55

        Err(err) => {
            tracing::warn!(
                ?err,
                "cannot format-preserve app YAML edit; \
                 rewriting the file without preserving formatting"
            );
            Ok(serde_yaml::to_string(target)?)
        }
    }
}

fn try_format_preserving_edit(text: &str, target: &Value) -> anyhow::Result<String> {
    let doc = Document::from_str(text)
        .map_err(|e| anyhow::anyhow!("could not parse YAML for format-preserving edit: {e}"))?;
    // Second parse, used to detect which keys changed. `yaml_edit` node text
    // cannot be reparsed for this: it is dedented on the first line only, so
    // block values are not valid standalone YAML.
    let original: Value = serde_yaml::from_str(text)
        .map_err(|e| anyhow::anyhow!("could not parse YAML semantically: {e}"))?;

    match (doc.as_mapping(), target, &original) {
        (Some(mapping), Value::Mapping(target_mapping), Value::Mapping(original_mapping)) => {
            merge_into_mapping(&mapping, target_mapping, Some(original_mapping), true)?;
            let out = doc.to_string();
            // Restore the leading comment block that `yaml_edit` drops (see
            // `leading_trivia`).
            let header = leading_trivia(text);
            if !header.is_empty() && !out.starts_with(header) {
                Ok(format!("{header}{out}"))
            } else {
                Ok(out)
            }
        }
        // The document root is not a mapping (or the target is not a mapping).
        // We have no formatting to preserve in a meaningful way, so fall back to
        // a plain serialization of the target.
        _ => Ok(serde_yaml::to_string(target)?),

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Simplify the YAML: remove multiple documents, complex keys, or anchors/aliases that a strict parser may reject.
  2. Check the inner `{e}` from serde_yaml for the exact deserialization complaint and fix that construct.
  3. Ensure serde_yaml and yaml_edit crate versions are compatible (update the CLI to the latest release).
  4. Reformat block values into standard flow/block style that both parsers handle identically.
  5. As a workaround, apply the config change manually in the file instead of via format-preserving edit.

Example fix

// before (complex key serde_yaml may reject)
? [debug, verbose]
: true
// after
debug_verbose: true
Defensive patterns

Strategy: validation

Validate before calling

// ensure the document is a single, simple mapping both parsers accept
fn validate_simple_yaml(path: &Path) -> anyhow::Result<()> {
    let text = std::fs::read_to_string(path)?;
    anyhow::ensure!(text.matches("---").count() <= 1, "multi-document YAML not supported");
    anyhow::ensure!(!text.contains("? "), "complex mapping keys not supported");
    let v: serde_yaml::Value = serde_yaml::from_str(&text)?;
    anyhow::ensure!(v.is_mapping(), "top level must be a mapping");
    Ok(())
}

Try / catch

match apply_app_config_to_yaml(&text, &cfg) {
    Ok(out) => out,
    Err(e) if e.to_string().contains("could not parse YAML semantically") => {
        eprintln!("Simplify YAML constructs (anchors, complex keys, multi-docs): {e}");
        std::process::exit(1);
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Document::from_str succeeded but serde_yaml::from_str::<Value> failed — typically documents with YAML features serde_yaml cannot represent into a Value mapping here, or edge-case incompatibility between the yaml_edit and serde_yaml parsers on the same text.

Common situations: Config files using exotic YAML constructs (complex mapping keys like `? [a, b]`, unusual anchors/aliases, multiple documents `---` in one file) where the two parsers disagree; a serde_yaml version change altering accepted syntax.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/6d3a2cc9654c0846. Report an issue: GitHub.