linera-io/linera-protocol · error

ProcessDeposit not committed: {other:?}

Error message

ProcessDeposit not committed: {other:?}

What it means

The relay submitted ProcessDeposit operations via chain_client.execute_operations and the outcome was not ClientOutcome::Committed — it was WaitForTimeout (the bridge chain is multi-owner and this client is not the current leader) or Conflict (another block was committed at the same height first). The deposit operations therefore did not land in this block.

Source

Thrown at linera-bridge/src/relay/mod.rs:654

                                count = operations.len(),
                                "Submitting ProcessDeposit operations..."
                            );

                            chain_client.synchronize_from_validators().await
                                .context("failed to synchronize")?;

                            let outcome = chain_client
                                .execute_operations(operations, vec![])
                                .await?;
                            match outcome {
                                linera_core::data_types::ClientOutcome::Committed(cert) => {
                                    tracing::info!(
                                        height = %cert.block().header.height,
                                        "ProcessDeposit committed"
                                    );
                                }
                                other => {
                                    anyhow::bail!("ProcessDeposit not committed: {other:?}");
                                }
                            };
                            Ok(())
                        }.await;
                        if response.send(result).is_err() {
                            tracing::debug!("ProcessDeposit response receiver dropped");
                        }
                        update_balance_metrics(&evm_client, &linera_client).await;
                    }
                }
            }
        }
    }

    Ok(())
}

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. If WaitForTimeout: this is usually transient — retry after synchronizing; leadership rotation lets the same operations commit in a later round.
  2. If Conflict: run chain_client.synchronize_from_validators() and retry — the conflicting block often already contains the deposits; verify the deposit was processed (query isDepositProcessed) before resubmitting.
  3. Ensure only one relay instance operates the bridge chain at a time to avoid chronic conflicts.
  4. Treat the error as retryable at the monitor/retry layer rather than fatal.

Example fix

// before
other => {
    anyhow::bail!("ProcessDeposit not committed: {other:?}");
}

// after: branch on the outcome for retry semantics
match outcome {
    ClientOutcome::Committed(cert) => tracing::info!(height = %cert.block().header.height, "ProcessDeposit committed"),
    ClientOutcome::WaitForTimeout(t) => anyhow::bail!(
        "ProcessDeposit deferred: not leader until {}; retry after round change", t.timestamp),
    ClientOutcome::Conflict(cert) => anyhow::bail!(
        "ProcessDeposit conflicted with block {}; sync and re-check isDepositProcessed", cert.hash()),
}
Defensive patterns

Strategy: retry

Validate before calling

// Before resubmitting after a Conflict, verify whether the deposits were already
// processed by the competing block:
if monitor.query_deposit_processed(&deposit_key).await? { return Ok(()); }

Try / catch

match outcome {
    ClientOutcome::Committed(c) => Ok(c),
    ClientOutcome::WaitForTimeout(_) | ClientOutcome::Conflict(_) => {
        // transient on multi-owner chains: sync, re-check idempotency, retry
        chain_client.synchronize_from_validators().await?;
        Err(retryable) // let the retry loop resubmit
    }
}

Prevention

When it happens

Trigger: Another relay instance or the leader client concurrently processes the same inbox/deposits (Conflict); the bridge chain's round leadership is held by a different owner during a multi-owner round, so execute_operations returns WaitForTimeout until the round changes.

Common situations: Running two relay instances against the same bridge chain (one wins, the other conflicts); rotating leadership on a multi-owner committee chain where the relay must wait its turn; a stale client that has not synchronized the latest block height racing a concurrent submitter.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/c37d39c915f9f0ab. Report an issue: GitHub.