FuelLabs/sway · error · anyhow::Error

Serialized receipts does not contain {} th index

Error message

Serialized receipts does not contain {} th index

What it means

In format_log_receipts, receipts are serialized once with serde_json::to_value and then mutated per index to hex-encode LogData payloads. The ok_or_else guard fires if the serialized array lacks an element at rec_index — which cannot normally happen because both come from the same &[Receipt] slice. It is a defensive invariant check, not an expected runtime condition.

Source

Thrown at forc-util/src/tx_utils.rs:25

use sway_core::{asm_generation::ProgramABI, fuel_prelude::fuel_tx};

/// Added salt used to derive the contract ID.
#[derive(Debug, Args, Default, Deserialize, Serialize)]
pub struct Salt {
    /// Added salt used to derive the contract ID.
    ///
    /// By default, this is
    /// `0x0000000000000000000000000000000000000000000000000000000000000000`.
    #[clap(long = "salt")]
    pub salt: Option<fuel_tx::Salt>,
}

/// Format `Log` and `LogData` receipts.
pub fn format_log_receipts(receipts: &[fuel_tx::Receipt], pretty_print: bool) -> Result<String> {
    let mut receipt_to_json_array = serde_json::to_value(receipts)?;
    for (rec_index, receipt) in receipts.iter().enumerate() {
        let rec_value = receipt_to_json_array.get_mut(rec_index).ok_or_else(|| {
            anyhow::anyhow!(
                "Serialized receipts does not contain {} th index",
                rec_index
            )
        })?;
        match receipt {
            fuel_tx::Receipt::LogData {
                data: Some(data), ..
            } => {
                if let Some(v) = rec_value.pointer_mut("/LogData/data") {
                    *v = hex::encode(data).into();
                }
            }
            fuel_tx::Receipt::ReturnData {
                data: Some(data), ..
            } => {
                if let Some(v) = rec_value.pointer_mut("/ReturnData/data") {
                    *v = hex::encode(data).into();
                }

View on GitHub (pinned to 47e5e902fa)

Solutions

  1. Treat it as a bug: report the fuel-tx/froc version combination to FuelLabs
  2. Pin fuel-tx/forc versions to a known-good pair until fixed
  3. As a workaround, print raw receipts without pretty_print
Defensive patterns

Strategy: try-catch

Try / catch

// Defensive invariant; practically unreachable. If it fires, capture versions and report.
match forc_util::format_log_receipts(&receipts, true) {
    Ok(s) => println!("{s}"),
    Err(e) if e.to_string().contains("Serialized receipts") => {
        eprintln!("internal error formatting receipts (fuel-tx bug?); versions: {}", versions());
        // fall back to debug printing the raw receipts
        println!("{receipts:#?}");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Essentially unreachable via normal API use: it would require serde_json to serialize a Receipt sequence to a shorter array than its input (e.g. a Receipt variant whose Serialize impl emits a non-array element or skips values).

Common situations: Virtually none for end users; a fuel-tx version whose Receipt Serialize impl violates round-trip expectations could surface it during pretty-printed test logs (`forc test --pretty-print` / print_logs).

Related errors


AI-assisted analysis of FuelLabs/sway@47e5e902fa (2026-08-16). Data as JSON: /api/errors/9136fc9d8b5effc1. Report an issue: GitHub.