linera-io/linera-protocol · error · anyhow
Query "{}" failed after {} retries.
Error message
Query "{}" failed after {} retries. What it means
`query_node` POSTs a GraphQL query to the node service and inspects the JSON body: a top-level `errors` field makes it log the errors and retry; a transport timeout also retries; only a clean response with `data` returns. After `n_try` exhausted attempts it bails with the truncated query text and the attempt count. Each failed attempt logs a warn with the GraphQL errors, so the bail is the aggregate of a consistently failing query.
Source
Thrown at linera-service/src/cli_wrappers/wallet.rs:1959
"Query \"{}\" failed: {}",
truncate_query_output(query),
response
.text()
.await
.unwrap_or_else(|error| format!("Could not get response text: {error}"))
);
let value: Value = response.json().await.context("invalid JSON")?;
if let Some(errors) = value.get("errors") {
tracing::warn!(
"Query \"{}\" failed: {}",
truncate_query_output(query),
errors
);
} else {
return Ok(value["data"].clone());
}
}
bail!(
"Query \"{}\" failed after {} retries.",
truncate_query_output(query),
n_try
);
}
/// Creates an application from a published module via the `createApplication` mutation.
pub async fn create_application<
Abi: ContractAbi,
Parameters: Serialize,
InstantiationArgument: Serialize,
>(
&self,
chain_id: &ChainId,
module_id: &ModuleId<Abi, Parameters, InstantiationArgument>,
parameters: &Parameters,
argument: &InstantiationArgument,
required_application_ids: &[ApplicationId],View on GitHub (pinned to 6c226ddcb3)
Solutions
- Check the warn logs — each attempt logs the exact GraphQL errors the service returned
- Verify the query itself: chain ID format, field names, and that the service tracks the chain
- Ensure the node service has started and finished critical syncing before issuing queries
- Retry after the service recovers, or call query_node with a higher retry count if the API allows it
Defensive patterns
Strategy: retry
Validate before calling
// Only issue queries the service can answer: chain must be tracked.
if !client.query_applications_list().await?.iter().any(/* ... */) {
// wait for service readiness instead of burning all retries
tokio::time::sleep(Duration::from_secs(1)).await;
} Try / catch
match client.query_node(query).await {
Err(e) if e.to_string().contains("failed after") => {
// retries already exhausted: the query itself is likely wrong,
// check the per-attempt GraphQL errors in the warn logs before retrying
log::error!("query permanently failed: {e}");
return Err(e);
}
result => result,
} Prevention
- Wait for service readiness (first successful query) before firing the real queries in tests
- Validate chain IDs and field names once — a bad query fails all retries by construction
- Watch the per-attempt warn logs: they contain the actual GraphQL errors, the bail only counts attempts
When it happens
Trigger: Every attempt returns GraphQL errors — querying a chain the service does not track, unknown/misnamed fields, unauthorized subscriptions — or every attempt times out against an overloaded or dead service.
Common situations: Integration tests racing ahead of chain/application creation; node service still syncing after startup; schema changes between wrapper and service versions; service starved under load so reqwest times out repeatedly.
Related errors
- Expected a tip hash string, but got {invalid_data:?} instead
- Failed to start node service
- no subscription queries registered
- There are {} owners but {} weights.
- Query {argument:?} is invalid and could not be deserialized
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/d4bb7a28107c3e7f.
Report an issue: GitHub.