linera-io/linera-protocol · error · async_graphql::Error

There are {} owners but {} weights.

Error message

There are {} owners but {} weights.

What it means

The `openMultiOwnerChain` GraphQL mutation creates a chain owned by several accounts with optional weighted voting. When `weights` is provided it must contain exactly one u64 per entry of `owners`; a length mismatch fails validation before anything is submitted on-chain. Without `weights`, every owner gets weight 100.

Source

Thrown at linera-service/src/node_service.rs:515

            default = 10_000
        )]
        base_timeout_ms: u64,
        #[graphql(
            desc = "The number of milliseconds by which the timeout increases after each \
                    single-leader round",
            default = 1_000
        )]
        timeout_increment_ms: u64,
        #[graphql(
            desc = "The age of an incoming tracked or protected message after which the \
                    validators start transitioning the chain to fallback mode, in milliseconds.",
            default = 86_400_000
        )]
        fallback_duration_ms: u64,
    ) -> Result<ChainId, Error> {
        let owners = if let Some(weights) = weights {
            if weights.len() != owners.len() {
                return Err(Error::new(format!(
                    "There are {} owners but {} weights.",
                    owners.len(),
                    weights.len()
                )));
            }
            owners.into_iter().zip(weights).collect::<Vec<_>>()
        } else {
            owners
                .into_iter()
                .zip(iter::repeat(100))
                .collect::<Vec<_>>()
        };
        let multi_leader_rounds = multi_leader_rounds.unwrap_or(u32::MAX);
        let timeout_config = TimeoutConfig {
            fast_round_duration: fast_round_ms.map(TimeDelta::from_millis),
            base_timeout: TimeDelta::from_millis(base_timeout_ms),
            timeout_increment: TimeDelta::from_millis(timeout_increment_ms),
            fallback_duration: TimeDelta::from_millis(fallback_duration_ms),

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Make `weights.length === owners.length` before sending, or omit `weights` entirely for uniform weight 100.
  2. Build (owner, weight) pairs in one place and unzip them into the two mutation arguments.
  3. Validate the pair arrays in the UI/DTO layer so a mismatch can never reach the mutation.

Example fix

// before
const owners = [u1, u2, u3], weights = [100, 100];
await gql.openMultiOwnerChain({ owners, weights }); // 'There are 3 owners but 2 weights.'

// after
const pairs = [[u1, 100], [u2, 100], [u3, 100]];
await gql.openMultiOwnerChain({ owners: pairs.map(p => p[0]), weights: pairs.map(p => p[1]) });
Defensive patterns

Strategy: validation

Validate before calling

if (weights && weights.length !== owners.length) throw new Error(`owners (${owners.length}) and weights (${weights.length}) must have equal length`);

Type guard

function isValidOwnerWeights(owners: unknown[], weights: unknown[] | null | undefined): boolean { return weights == null || (Array.isArray(owners) && Array.isArray(weights) && weights.length === owners.length); }

Try / catch

try { await gql.openMultiOwnerChain({ owners, weights }); } catch (e) { if (/owners but .* weights/i.test(e.message)) { /* fix arrays and resubmit */ } else throw e; }

Prevention

When it happens

Trigger: Calling `openMultiOwnerChain(owners: [a, b, c], weights: [100, 100])` — three owners but two weights, or vice versa; building the two arrays from separate loops that got out of sync.

Common situations: Frontend forms that collect owners and weights in separate lists; scripts that copy an owners array but edit the weights array; partial updates adding an owner without a weight.

Related errors


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