Skip to content

fix: remove source error interpolation from #[error] format strings#3172

Open
mitchmindtree wants to merge 3 commits into
stagingfrom
mitchmindtree/fix-error-fmt
Open

fix: remove source error interpolation from #[error] format strings#3172
mitchmindtree wants to merge 3 commits into
stagingfrom
mitchmindtree/fix-error-fmt

Conversation

@mitchmindtree
Copy link
Copy Markdown
Collaborator

@mitchmindtree mitchmindtree commented Mar 4, 2026

Context

@kaimast mentioned he's looking into improving Display consistency for errors across snarkvm, and it made me realise the error formatting of some of the errors I introduced (in #3081, #3082) is incorrect.

Several of the thiserror error types I added interpolate #[from] fields in their #[error("...")] format strings (e.g. #[error("VM execution failed: {0}")] where {0} is #[from] SomeError). Because #[from] implies #[source], the inner error's message appears in both Display output and the source() chain - causing duplication when consumers walk the chain. The std Error docs explicitly advise against this:

expose the inner error via source() or render it in Display, but not both.

Further Context

This is an issue because when an error is surfaced by an app downstream, they often need to have control over how to format the error. E.g. in some cases they may only want to surface the top-level error, in others they may want to present the full causal chain.

anyhow offers the ability to easily format either style:

  • {} (Display) - prints only the outermost error message
  • {:#} (alternate Display) - prints the full chain, e.g. "Failed to read instrs from ./path: No such file or directory (os error 2)"
  • {:?} (Debug) - prints the full chain plus backtrace

which is another part of what makes it better-suited for app-level error handling.

The Fix

This PR removes the interpolation from the format string so each layer only describes its own context. The inner error remains accessible via source().

@mitchmindtree mitchmindtree self-assigned this Mar 4, 2026
@mitchmindtree mitchmindtree changed the title fix: remove source error interpolation from #[error] format strings fix: WIP - remove source error interpolation from #[error] format strings Mar 4, 2026
Remove interpolation of `#[from]`/`#[source]` fields from `#[error("...")]`
attributes. Since `#[from]` implies `#[source]`, the inner error message
was duplicated in both `Display` output and the `source()` chain. Each
layer now only describes its own context while inner errors remain
accessible via `source()`.

Also fix `IndexedInstructionError` to use `#[source]` instead of
interpolating the error field in the format string.

Update the test harness to format errors via `anyhow::Error`'s `{:#}`
(alternate Display), which walks the `source()` chain. This preserves
the full error context in test expectations.
Remove source error interpolation from #[error] format strings on
`#[from]` variants across utilities, fields, and algorithms crates.
When thiserror sees both #[from] and a format string that interpolates
the inner error, it produces duplicated output (the message printed
twice). Using #[error(transparent)] delegates Display and source()
correctly.
…rrors

Group A — replace trivial manual `From` impls with `#[from]`:
- `SynthesisError::IoError`: add `#[from]`, delete manual `From<std::io::Error>` impl
- `AHPError::ConstraintSystemError`: add `#[from]`, delete manual `From<SynthesisError>` impl
- `GroupError::FieldError`: add `#[from]`, delete manual `From<FieldError>` impl

Group B — add `#[source]` to named-field variants in `CheckBlockError`:
- `InvalidPrefix`: add `#[source]` on `error` field, fix typo ("as" → "has"),
  remove `{error:?}` interpolation
- `SpeculationFailed`: add `#[source]` on `inner`, remove `{inner}` interpolation
- `VerificationFailed`: add `#[source]` on `inner`, remove `{inner}` interpolation

Format strings no longer interpolate `#[source]` fields, avoiding the
duplication bug fixed in the prior commit. The inner errors remain
accessible via `Error::source()`, enabling proper error chain traversal.
@mitchmindtree mitchmindtree force-pushed the mitchmindtree/fix-error-fmt branch from 4c7902a to f3b0097 Compare March 4, 2026 08:02
@mitchmindtree mitchmindtree changed the title fix: WIP - remove source error interpolation from #[error] format strings fix: remove source error interpolation from #[error] format strings Mar 4, 2026
@mitchmindtree mitchmindtree requested a review from kaimast March 4, 2026 08:27
@mitchmindtree mitchmindtree marked this pull request as ready for review March 4, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant