unionlabs/union · error

not implemented

Error message

not implemented

What it means

The state-lens ICS23 SMT light client implements verify_membership (including proof-with-value handling) but leaves verify_non_membership as unimplemented!(). Any proof-of-absence submitted against this client type traps with "not implemented" and the message reverts.

Source

Thrown at cosmwasm/lightclient/state-lens-ics23-smt/src/client.rs:65

        let client_state = ctx.read_self_client_state()?;
        let consensus_state = ctx.read_self_consensus_state(height)?;
        verify_membership(
            &key,
            consensus_state.state_root,
            AccountAddress(client_state.extra.table_handle),
            storage_proof,
            &value,
        )
        .map_err(Into::into)
    }

    fn verify_non_membership(
        _ctx: IbcClientCtx<Self>,
        _height: u64,
        _key: Vec<u8>,
        _storage_proof: Self::StorageProof,
    ) -> Result<(), IbcClientError<Self>> {
        unimplemented!()
    }

    fn get_timestamp(consensus_state: &Self::ConsensusState) -> Timestamp {
        consensus_state.timestamp
    }

    fn get_latest_height(client_state: &Self::ClientState) -> u64 {
        client_state.l2_latest_height
    }

    fn get_counterparty_chain_id(client_state: &Self::ClientState) -> String {
        client_state.l2_chain_id.clone()
    }

    fn status(ctx: IbcClientCtx<Self>, client_state: &Self::ClientState) -> Status {
        ctx.status(client_state.l1_client_id)
            .unwrap_or(Status::Frozen)
    }

View on GitHub (pinned to 031785bb6d)

Solutions

  1. Gate absence-proof flows off for state-lens SMT clients in the relayer
  2. Upgrade the deployed client wasm when verify_non_membership is implemented (SMT null-leaf proofs make this feasible)
  3. If you maintain the contract, implement the null-leaf verification path instead of the stub
  4. Check the union spec/contract version deployed on both ends of the channel
Defensive patterns

Strategy: validation

Validate before calling

const NO_NON_MEMBERSHIP = new Set(["movement", "state-lens-ics23-smt", "sui"])
if (msg.kind === "nonMembership" && NO_NON_MEMBERSHIP.has(clientType)) {
  throw new Error(`${clientType} does not implement verify_non_membership`)
}

Type guard

const supportsNonMembership = (clientType: string) =>
  !new Set(["movement", "state-lens-ics23-smt", "sui"]).has(clientType)

Prevention

When it happens

Trigger: A relayer submits a non-membership proof (absence of a key in the counterparty L2 state) to a state-lens-ics23-smt union client — e.g., proving a channel or association does not exist during cleanup/error-handling flows that require absence proofs.

Common situations: Relayer flows ported from client types with absence-proof support; spec-conformance tests that exercise the whole trait; newer relayer logic that opportunistically submits non-membership proofs.

Related errors


AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16). Data as JSON: /api/errors/29f8fa1b0c8bb59b. Report an issue: GitHub.