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
- Simplify the YAML: remove multiple documents, complex keys, or anchors/aliases that a strict parser may reject.
- Check the inner `{e}` from serde_yaml for the exact deserialization complaint and fix that construct.
- Ensure serde_yaml and yaml_edit crate versions are compatible (update the CLI to the latest release).
- Reformat block values into standard flow/block style that both parsers handle identically.
- 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
- Keep app config YAML to plain key/value mappings
- Avoid multiple documents (---) in one config file
- Pin and update CLI versions together with serde_yaml/yaml_edit fixes
- Round-trip the file through a parser in CI to catch parser-compat regressions
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
- could not parse YAML for format-preserving edit: {e}
- Unable to determine the wasmer dir: {e}
- Could not parse app.yaml: {err:?}
- Invalid job trigger '{s}'. Must be 'pre-deployment', 'post-d
- not a `sys` backend!
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/6d3a2cc9654c0846.
Report an issue: GitHub.