wasmerio/wasmer · error

could not parse YAML for format-preserving edit: {e}

Error message

could not parse YAML for format-preserving edit: {e}

What it means

try_format_preserving_edit in lib/cli/src/utils/yaml.rs first parses the YAML text with yaml_edit's `Document::from_str` to preserve comments/formatting while editing app config. If the text is not syntactically valid YAML, the parse fails with this error before any merge is attempted. It is the syntax-level (format-preserving) parse failure, distinct from the semantic serde_yaml parse that follows.

Source

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

                "format-preserving app YAML edit produced invalid YAML; \
                 rewriting the file without preserving formatting"
            );
            Ok(serde_yaml::to_string(target)?)
        }
        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)
            }

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Fix the YAML syntax at the reported position from the inner `{e}` (tabs are illegal for indentation — replace with spaces).
  2. Validate the file with an external linter: `yamllint <file>` or paste into a YAML validator.
  3. Remove merge-conflict markers or unrendered template placeholders before running the command.
  4. Confirm the target file is actually a YAML config, not TOML/JSON.
  5. If the file cannot be repaired, regenerate a minimal valid config and re-apply the desired settings.

Example fix

// before (invalid: tab indentation)
# app.yaml
kind:
\tapp: my-app
// after
kind:
  app: my-app
Defensive patterns

Strategy: validation

Validate before calling

// validate YAML syntax before handing it to format-preserving edit
fn validate_yaml(path: &Path) -> anyhow::Result<()> {
    let text = std::fs::read_to_string(path)?;
    serde_yaml::from_str::<serde_yaml::Value>(&text)
        .map_err(|e| anyhow::anyhow!("{} is not valid YAML: {}", path.display(), e))?;
    anyhow::ensure!(!text.contains('\t'), "{} uses tab indentation — not valid YAML", path.display());
    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") => {
        eprintln!("Fix YAML syntax first (no tabs, balanced quotes/brackets): {e}");
        std::process::exit(1);
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: apply_app_config_to_yaml is given a config file whose content is not valid YAML — tabs used for indentation, unclosed quotes/brackets, duplicate anchors, or a file that is not YAML at all (JSON5, TOML, binary).

Common situations: Hand-edited app.yaml with tab indentation; a template engine left an unrendered placeholder like {{ .Value }} producing invalid syntax; user pointed the CLI at the wrong file (e.g. a TOML config); merge conflict markers (<<<<<<<) left in the file.

Related errors


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