linera-io/linera-protocol · error · anyhow

Query result subscription failed: {errors:?}

Error message

Query result subscription failed: {errors:?}

What it means

Raised by the NodeExt test wrapper (cli_wrappers/wallet.rs) when the GraphQL websocket subscription `subscription { queryResult(name:..., chainId:..., applicationId:...) }` against `ws://localhost:{port}/ws` returns an `errors` array in a payload message. The node accepted the websocket connection but failed the queryResult subscription server-side. It is delivered asynchronously as an `Err` item on the returned stream of JSON values.

Source

Thrown at linera-service/src/cli_wrappers/wallet.rs:2133

            text == "{\"type\":\"connection_ack\"}",
            "Unexpected response: {text}"
        );
        let query_json = json!({
          "id": "1",
          "type": "start",
          "payload": {
            "query": query,
            "variables": {},
            "operationName": null
          }
        });
        websocket.send(query_json.to_string().into()).await?;
        Ok(Box::pin(websocket.map_err(anyhow::Error::from).and_then(
            |message| async {
                let text = message.into_text()?;
                let value: Value = serde_json::from_str(&text).context("invalid JSON")?;
                if let Some(errors) = value["payload"].get("errors") {
                    bail!("Query result subscription failed: {errors:?}");
                }
                Ok(value["payload"]["data"]["queryResult"].clone())
            },
        )))
    }
}

/// A running faucet service.
pub struct FaucetService {
    port: u16,
    child: Child,
    _temp_dir: tempfile::TempDir,
    terminated: bool,
}

impl Drop for FaucetService {
    fn drop(&mut self) {
        if !self.terminated {

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Confirm the application is registered on that chain (check via a one-shot GraphQL query for the chain's applications) and fix the application ID
  2. Verify the query `name` matches a query in the application's generated GraphQL schema
  3. Rebuild harness and node binaries from the same commit to eliminate schema/formatting differences
  4. Re-create the subscription — the stream dies once the node has sent the error payload

Example fix

// before
let query = format!(
    r#"subscription {{ queryResult(name: "{name}", chainId: "{chain_id}", applicationId: "{application_id}") }}"#
);

// after — always inspect each stream item for the server-side error
let mut stream = node.query_result(name, chain_id, application_id).await?;
while let Some(item) = stream.next().await {
    let value = item.context("queryResult stream ended with error")?;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: confirm the application is registered on the chain before subscribing
let response = node
    .query_node(&format!(
        "query {{ applications(chainId: \"{chain_id}\") {{ applicationId }} }}"
    ))
    .await?;
let registered = response["data"]["applications"]
    .as_array()
    .map(|apps| apps.iter().any(|a| a["applicationId"] == application_id.to_string()))
    .unwrap_or(false);
anyhow::ensure!(registered, "application {application_id} not registered on {chain_id}");

Try / catch

let mut stream = node.query_result(name, chain_id, application_id).await?;
while let Some(item) = stream.next().await {
    let value = match item {
        Ok(v) => v,
        Err(e) if e.to_string().contains("Query result subscription failed") => {
            // wrong applicationId / query name / untracked chain: fix inputs before retrying
            return Err(e.context("queryResult subscription rejected by node"));
        }
        Err(e) => return Err(e),
    };
    // handle value
}

Prevention

When it happens

Trigger: Calling `node.query_result(name, chain_id, application_id)` where the application ID is wrong or the application is not registered/running on that chain; the `name` does not match a query exposed by the application's GraphQL module; the chain is not tracked by the node; client/node version skew changes the queryResult schema or argument formatting.

Common situations: Integration tests that subscribe to an application's query results before publishing/registering the application; formatting mismatches of `ApplicationId`/`ChainId` (`e5:...:...:0` style strings) after an SDK upgrade; querying an application on a chain owned by a different shard/validator.

Related errors


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