linera-io/linera-protocol · error
expected an operation name after 'query', e.g. 'query MyQuer
Error message
expected an operation name after 'query', e.g. 'query MyQuery {{ ... }}' What it means
After consuming 'query' plus whitespace, parse_allowed_subscription extracts the leading alphanumeric/underscore run as the operation name; the name is the key clients later use to reference this subscription. This error fires when that run is empty — i.e. the text immediately after 'query ' is punctuation such as '{', ':' or end-of-string, so no name exists to register the query under.
Source
Thrown at linera-service/src/query_subscription.rs:45
/// 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(),
})
}
/// Parses a `Name=Secs` string into a query name and TTL in seconds.
pub fn parse_subscription_ttl(s: &str) -> Result<(String, u64), String> {
let (name, secs) = s
.split_once('=')
.ok_or_else(|| format!("expected format Name=Secs, got: {s}"))?;
let secs: u64 = secs
.parse()
.map_err(|e| format!("invalid seconds value '{secs}': {e}"))?;
Ok((name.to_string(), secs))View on GitHub (pinned to 6c226ddcb3)
Solutions
- Name the operation: 'query { transfers { id } }' becomes 'query Transfers { transfers { id } }'
- Make sure the whole query string is one shell argument (quote it) so the name and body are not lost
- Use the same name later in --subscription-ttl entries and in subscription requests, since the extracted name is the registry key
Example fix
# before
--allow-subscription 'query { transfers { id } }'
# after
--allow-subscription 'query Transfers { transfers { id } }' Defensive patterns
Strategy: validation
Validate before calling
// Rust: require a non-empty name after 'query'
fn subscription_has_name(s: &str) -> bool {
let t = s.trim();
let Some(rest) = t.strip_prefix("query") else { return false };
if !rest.starts_with(char::is_whitespace) { return false; }
let rest = rest.trim_start();
let name = rest.split(|c: char| !c.is_alphanumeric() && c != '_').next().unwrap_or_default();
!name.is_empty()
} Type guard
fn has_named_query_operation(s: &str) -> bool { subscription_has_name(s) } Try / catch
if let Err(e) = parse_allowed_subscription(&arg) {
log::warn!("skipping subscription {arg:?}: {e:#}");
failures.push(arg);
} Prevention
- Standardize on named GraphQL operations in your project's query files
- Lint subscription strings in CI the same way you lint config files
- Remember the extracted name is the registry key — reuse it verbatim in TTL entries and client requests
When it happens
Trigger: Passing an anonymous GraphQL operation via --allow-subscription, e.g. 'query { transfers { id } }', or something degenerate like 'query :' or 'query '. Parsing happens at node startup inside run(), so the process exits immediately.
Common situations: Anonymous queries are legal GraphQL and most clients accept them, so users paste a working query from graphiql/curl only to have the node reject it; also truncated arguments cut off by shell word-splitting.
Related errors
- expected whitespace after 'query' keyword
- expected query to start with 'query', got: {s}
- no subscription query registered with name '{}'
- The input has not matched: {input}
- Invalid application ID
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/c7fab6ba0f057a50.
Report an issue: GitHub.