linera-io/linera-protocol · error
expected query to start with 'query', got: {s}
Error message
expected query to start with 'query', got: {s} What it means
A --allow-subscription value did not start with the literal keyword `query`. parse_allowed_subscription only accepts strings of the shape `query Name { ... }` — it strips the prefix "query", requires whitespace right after it, then extracts the operation name used to register the subscription.
Source
Thrown at linera-service/src/query_subscription.rs:33
use tokio::sync::watch;
use tokio_util::sync::CancellationToken;
use tracing::{debug, warn};
/// A named GraphQL query string registered at startup via `--allow-subscription`.
#[derive(Clone, Debug)]
pub struct RegisteredQuery {
/// The operation name used to refer to the query.
pub name: String,
/// The full GraphQL query string.
pub query: String,
}
/// Parses a GraphQL query string like `query Name { ... }` and extracts the operation name.
pub fn parse_allowed_subscription(s: &str) -> anyhow::Result<RegisteredQuery> {
let trimmed = s.trim();
let rest = trimmed
.strip_prefix("query")
.ok_or_else(|| anyhow::anyhow!("expected query to start with 'query', got: {s}"))?;
// The character right after "query" must be whitespace (not part of a longer word).
anyhow::ensure!(
rest.starts_with(char::is_whitespace),
"expected whitespace after 'query' keyword"
);
let rest = rest.trim_start();
// Extract the operation name: sequence of alphanumeric/underscore chars.
let name = rest
.split(|c: char| !c.is_alphanumeric() && c != '_')
.next()
.unwrap_or_default();
anyhow::ensure!(
!name.is_empty(),
"expected an operation name after 'query', e.g. 'query MyQuery {{ ... }}'"
);
Ok(RegisteredQuery {
name: name.to_string(),
query: trimmed.to_string(),View on GitHub (pinned to 6c226ddcb3)
Solutions
- Prefix the document with the keyword and a name: `query Transfers { transfers { amount } }`.
- Do not use `subscription` documents — this flag registers polled queries, and only the `query` keyword is accepted.
- Keep whitespace between `query` and the operation name.
- Pick a stable operation name; it is the key used for later --subscription-ttl Name=Secs settings.
Example fix
# before
--allow-subscription 'subscription Transfers { transfers { amount } }'
# after
--allow-subscription 'query Transfers { transfers { amount } }' Defensive patterns
Strategy: validation
Validate before calling
let t = s.trim();
ensure!(
t == "query" || t.starts_with("query ") || t.starts_with("query\n"),
"--allow-subscription must start with the 'query' keyword, e.g. 'query Name {{ ... }}'"
); Type guard
fn is_query_operation(s: &str) -> bool {
let t = s.trim();
match t.strip_prefix("query") {
Some(rest) => rest.is_empty() || rest.starts(char::is_whitespace),
None => false,
}
} Prevention
- Register named query documents exactly as `query Name { ... }`.
- Do not pass `subscription` documents — only polled queries are supported.
- Keep whitespace between the keyword and the operation name; reuse the name for TTL settings.
When it happens
Trigger: Passing a `subscription ...` document, a bare query body `{ transfers { amount } }` with no keyword, or a keyword glued to the name (`queryTransfers`) — the last one instead trips the whitespace check, but a missing/other keyword trips this error.
Common situations: Registering actual GraphQL subscriptions (not supported here — only named queries); copy-pasting query bodies from GraphQL playgrounds that omit the keyword; assuming the parser accepts shorthand queries.
Related errors
- expected whitespace after 'query' keyword
- expected an operation name after 'query', e.g. 'query MyQuer
- Expected a tip hash string, but got {invalid_data:?} instead
- Notification subscription failed: {errors:?}
- Query result subscription failed: {errors:?}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/c1767fee9069784e.
Report an issue: GitHub.