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
- Restart the node with --allow-subscription 'query <Name> { ... }' where <Name> exactly matches the name used in subscription requests (case-sensitive)
- Verify the registry with QuerySubscriptionManager::get_query(name) (it returns Option) or by re-reading the startup flags
- 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
- Keep the list of --allow-subscription values in version control next to the node launch scripts
- Health-check endpoint: expose get_query(name) results so clients can verify names before subscribing
- Use identical, case-sensitive operation names in registration flags, TTL config, and client code
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
- expected whitespace after 'query' keyword
- expected an operation name after 'query', e.g. 'query MyQuer
- Notification subscription failed: {errors:?}
- Query result subscription failed: {errors:?}
- expected query to start with 'query', got: {s}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/71527c6ca4e17150.
Report an issue: GitHub.