linera-io/linera-protocol · error

no subscription query registered with name '{}'

Error message

no subscription query registered with name '{}'

What it means

QuerySubscriptionManager::subscribe resolves a SubscriptionKey (operation name + chain + application) against the queries registered at startup from --allow-subscription. This error means a subscription request referenced an operation name that is not in that registry, so there is no query string to run for the watcher.

Source

Thrown at linera-service/src/query_subscription.rs:125

    /// Returns the GraphQL query string for a given name, if registered.
    pub fn get_query(&self, name: &str) -> Option<&str> {
        self.queries.get(name).map(|s| s.as_str())
    }

    /// Returns a watch receiver for the given key. Lazily spawns a watcher if needed.
    /// The receiver initially holds `None`; the watcher populates it with `Some(value)`
    /// after the first query. Callers should filter out `None` values from the stream.
    pub fn subscribe<C: ClientContext + 'static>(
        self: &Arc<Self>,
        key: &SubscriptionKey,
        context: Arc<futures::lock::Mutex<C>>,
        token: CancellationToken,
    ) -> anyhow::Result<watch::Receiver<Option<String>>> {
        let query_string = self
            .get_query(&key.name)
            .ok_or_else(|| {
                anyhow::anyhow!("no subscription query registered with name '{}'", key.name)
            })?
            .to_string();

        let mut watchers = self.watchers.lock().unwrap();

        // If a watcher already exists, reuse it.
        if let Some(state) = watchers.get(key) {
            return Ok(state.sender.subscribe());
        }

        // Create a new watch channel (initial value is None until the first query completes).
        let (sender, receiver) = watch::channel(None);
        watchers.insert(
            key.clone(),
            WatcherState {
                sender: sender.clone(),
            },
        );

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Restart the node with --allow-subscription 'query <Name> { ... }' where <Name> exactly matches the name used in subscription requests (case-sensitive)
  2. Verify the registry with QuerySubscriptionManager::get_query(name) (it returns Option) or by re-reading the startup flags
  3. Check for case differences and trailing whitespace in the name on both the registration and the request side

Example fix

# before
linera ... (node started without the flag; client subscribes to 'Notifs')
# after
linera ... --allow-subscription 'query Notifs { notifications { id } }'
Defensive patterns

Strategy: validation

Validate before calling

// Rust: check registration before subscribing
let query = manager.get_query(&key.name);
if query.is_none() {
    return Err(anyhow!("subscription {name} not registered; restart node with --allow-subscription 'query {name} {{ ... }}'", name = key.name));
}

Type guard

fn is_registered(manager: &QuerySubscriptionManager, name: &str) -> bool {
    manager.get_query(name).is_some()
}

Try / catch

match manager.subscribe(&key, context, token).await {
    Ok(rx) => { /* stream rx, skipping initial None */ }
    Err(e) if e.to_string().contains("no subscription query registered") => {
        // surface as a config problem: name unknown to this node
        return_service_error(StatusCode::NOT_FOUND, e);
    }
    Err(e) => return internal_error(e),
}

Prevention

When it happens

Trigger: Sending a GraphQL subscription request to the node's service whose operation name was never registered, e.g. requesting 'Notifs' when the node was started with --allow-subscription 'query Notifications { ... }'. Raised from subscribe() itself or from run_query_subscription_watcher when re-subscribing.

Common situations: Node restarted without the --allow-subscription flag; typo or case mismatch between the requested operation name and the registered one; deploying a new client version that renames operations against an old node config; TTL config referencing one name while requests use another.

Related errors


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