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
- Make `weights.length === owners.length` before sending, or omit `weights` entirely for uniform weight 100.
- Build (owner, weight) pairs in one place and unzip them into the two mutation arguments.
- 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
- Build (owner, weight) pairs in one structure and derive both arrays from it.
- Omit weights entirely for uniform weight 100.
- Validate array lengths at the form/DTO boundary.
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
- Query "{}" failed after {} retries.
- Expected a tip hash string, but got {invalid_data:?} instead
- invalid {label} hex: {e}
- no subscription queries registered
- invalid hex
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/a5522c8c63c4e340.
Report an issue: GitHub.