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

no subscription queries registered

Error message

no subscription queries registered

What it means

The node service's `queryResult` GraphQL subscription re-executes pre-registered application queries on every new block. Registrations are supplied only at startup: each `--allow-subscription 'query Name { ... }'` CLI flag populates the QuerySubscriptionManager; with no flags, `query_subscriptions` is `None` and any `queryResult(name, chainId, applicationId)` subscription fails immediately with this message.

Source

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

            .lock()
            .await
            .make_chain_client(chain_id)
            .await?;
        Ok(client.subscribe()?)
    }

    /// Subscribes to the result of a pre-registered GraphQL query.
    /// Re-executes the query on every new block and pushes changed results.
    async fn query_result(
        &self,
        #[graphql(desc = "Name of the registered subscription query.")] name: String,
        #[graphql(desc = "The chain to watch.")] chain_id: ChainId,
        #[graphql(desc = "The application to query.")] application_id: ApplicationId,
    ) -> Result<impl Stream<Item = RawJson>, Error> {
        let manager = self
            .query_subscriptions
            .as_ref()
            .ok_or_else(|| Error::new("no subscription queries registered"))?;

        let key = crate::query_subscription::SubscriptionKey {
            name,
            chain_id,
            application_id,
        };

        let receiver = manager
            .subscribe(
                &key,
                Arc::clone(&self.context),
                self.cancellation_token.clone(),
            )
            .map_err(|e| Error::new(e.to_string()))?;

        // `sender.subscribe()` marks the current value as "already seen", so
        // `WatchStream` would skip it and wait for the next change.  Grab the
        // current snapshot first and prepend it to the stream so that every new

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Restart the node service with `--allow-subscription 'query <Name> { ... }'` for every query you want registered (the flag is repeatable).
  2. Use the `notifications(chainId)` subscription instead if you only need block notifications, not re-executed query results.
  3. Make sure the operation name in your GraphQL subscription matches the name extracted from the registered query string.
  4. Add `--subscription-ttl-secs <Name>=<secs>` where caching is needed — it presupposes registration.

Example fix

# before
linera service ...  # no --allow-subscription flags; queryResult fails

# after
linera service ... --allow-subscription 'query CounterValue { getCounter { value } }'
Defensive patterns

Strategy: validation

Validate before calling

// before subscribing, confirm registration is part of your service config
const serviceArgs = readLaunchConfig();
if (!serviceArgs.allowSubscriptions?.length) throw new Error('queryResult requires --allow-subscription on the service');

Try / catch

try { const stream = gql.subscribe('queryResult { ... }'); } catch (e) { if (/no subscription queries registered/i.test(e.message)) { /* fall back to notifications(chainId) */ } else throw e; }

Prevention

When it happens

Trigger: Subscribing to `queryResult` against a `linera service` process started without any `--allow-subscription` flags; using a subscription name that was registered on a different service instance.

Common situations: Deploying the node service with an incomplete launch command; copying a subscription setup from one environment to another that lacks the flag; upgrading and dropping the flag from the service config.

Related errors


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