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
- Fix the YAML syntax at the reported position from the inner `{e}` (tabs are illegal for indentation — replace with spaces).
- Validate the file with an external linter: `yamllint <file>` or paste into a YAML validator.
- Remove merge-conflict markers or unrendered template placeholders before running the command.
- Confirm the target file is actually a YAML config, not TOML/JSON.
- 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
- Run yamllint (or a CI YAML check) on config files before applying changes
- Use spaces, never tabs, for YAML indentation
- Commit rendered config — don't ship unrendered template placeholders
- Resolve merge conflicts in YAML files before running CLI commands
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
- could not parse YAML semantically: {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/0705134977ef4425.
Report an issue: GitHub.