linera-io/linera-protocol · error · std::io::Error
failed to parse SNAP body in {path:?} as Formats: {e}
Error message
failed to parse SNAP body in {path:?} as Formats: {e} What it means
After stripping the frontmatter, load_formats_from_snap deserializes the remaining YAML body into linera_sdk::formats::Formats with serde_yaml_08. This error means the delimiters were fine but the YAML inside is either syntactically invalid or does not match the Formats schema (wrong field names, wrong types, missing required fields). The message includes the path and serde_yaml's parse/deserialize cause.
Source
Thrown at linera-client/src/client_context.rs:971
/// Reads an insta SNAP file containing a YAML-encoded `Formats` value and parses
/// it. The caller BCS-serializes the result to obtain the application formats
/// blob payload: BCS matches the documented intent (the blob is "the BCS
/// serialization of an application's `Formats`") and the encoding the explorer
/// decodes with.
#[cfg(feature = "fs")]
fn load_formats_from_snap(path: &std::path::Path) -> Result<linera_sdk::formats::Formats, Error> {
let content = fs::read_to_string(path).map_err(|e| {
std::io::Error::new(e.kind(), format!("failed to read SNAP file {path:?}: {e}"))
})?;
let body = strip_snap_frontmatter(&content).ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("SNAP file {path:?} is missing the `---` frontmatter delimiters"),
)
})?;
let formats = serde_yaml_08::from_str(body).map_err(|e| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("failed to parse SNAP body in {path:?} as Formats: {e}"),
)
})?;
Ok(formats)
}
#[cfg(feature = "fs")]
fn strip_snap_frontmatter(content: &str) -> Option<&str> {
let rest = content.strip_prefix("---\n")?;
let end = rest.find("\n---\n")?;
Some(&rest[end + "\n---\n".len()..])
}
#[cfg(not(web))]
impl<Env: Environment> ClientContext<Env> {
/// Prepares the chains and fungible tokens needed to run a benchmark.
pub async fn prepare_for_benchmark(View on GitHub (pinned to 6c226ddcb3)
Solutions
- Read the {e} cause in the message: a scan error points at a line/column to fix (tabs -> spaces, stray quote); a deserialize error names the offending field — rename or retype it to match Formats.
- Regenerate the snapshot with the linera-version you are publishing from (run the application's tests with that toolchain) so the body matches the current Formats schema, instead of hand-patching an old .snap.
- If you must edit, validate with serde_yaml 0.8 semantics (plain YAML 1.1/1.2 basics, LF, two-space indent) and compare field-for-field against a known-good snapshot in the same repo.
Example fix
# before (body inside the snap; breaks on tab indent / unknown field) --- source: format.rs --- formats: # tab indentation -> YAML scan error # after --- source: format.rs --- formats: - ...
Defensive patterns
Strategy: validation
Validate before calling
fn snap_body_parses(content: &str) -> bool {
let rest = content.strip_prefix("---\n")?;
let end = rest.find("\n---\n")?;
serde_yaml_08::from_str::<linera_sdk::formats::Formats>(&rest[end + 5..]).is_ok()
}
// (make it return bool by mapping Option->false in the caller) Type guard
fn is_parsable_formats(yaml_body: &str) -> bool {
serde_yaml_08::from_str::<serde_yaml_08::Value>(yaml_body).is_ok()
} Try / catch
match load_formats_from_snap(path) {
Ok(f) => f,
Err(e) if e.to_string().contains("failed to parse SNAP body") => {
anyhow::bail!("SNAP {path:?} body is not a valid Formats YAML: {e}; regenerate the snapshot")
}
Err(e) => return Err(e.into()),
} Prevention
- Regenerate snapshots with the same linera version you publish with, so schema and body always match.
- Never hand-edit generated .snap bodies; change the source of truth and let insta rewrite the snapshot.
- Add a CI lint that parses every .snap used for --formats with serde_yaml_08 before the publish job.
When it happens
Trigger: Passing --formats a .snap whose body is not valid YAML (tabs for indentation, a stray quote or colon, duplicated keys), or valid YAML that does not deserialize as Formats (renamed/removed fields, wrong nesting, a value of the wrong type for a version/encoding field). It fires after the frontmatter check succeeded.
Common situations: Editing a generated .snap by hand and breaking indentation; snapshots produced by an older/newer linera-version of Formats whose schema changed (field renames, added required entries); copying only part of a snapshot; merging snapshots with duplicate keys; YAML gotchas like unquoted strings starting with special characters or tabs pasted from a browser.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to read SNAP file {path:?}: {e}
- SNAP file {path:?} is missing the `---` frontmatter delimite
- bcs: {e}
- Default wallet directory is not supported in this platform:
- nonexistent chain `{chain_id}`
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/bdf51e12da29bb5b.
Report an issue: GitHub.