hasura/graphql-engine · error · RequestError::ExplainError
explain error: {0}
Error message
explain error: {0} What it means
RequestError::ExplainError is a catch-all for failures encountered while producing a query explanation (plan/preview) for a GraphQL request. It carries a String message describing what went wrong during the explain pipeline, prefixed with 'explain error: '. It is distinct from parse/validation errors: the request was understood, but explaining it failed.
Source
Thrown at v3/crates/graphql/frontend/src/error.rs:23
use tracing_util::{ErrorVisibility, TraceableError};
/// Request errors are raised before execution of root fields begins.
/// Ref: <https://spec.graphql.org/October2021/#sec-Errors.Request-errors>
#[derive(Debug, thiserror::Error)]
pub enum RequestError {
#[error("parsing failed: {0}")]
ParseFailure(#[from] gql::ast::spanning::Positioned<gql::parser::Error>),
#[error("validation failed: {0}")]
ValidationFailed(#[from] gql::validation::Error),
#[error("{0}")]
IRConversionError(#[from] graphql_ir::Error),
#[error("{0}")]
GraphQlPlanError(#[from] graphql_ir::GraphqlIrPlanError),
#[error("explain error: {0}")]
ExplainError(String),
}
impl RequestError {
pub fn to_graphql_error(&self, expose_internal_errors: ExposeInternalErrors) -> GraphQLError {
let message = match (self, expose_internal_errors) {
// Error messages for internal errors from IR conversion and Plan generations are masked.
(
Self::IRConversionError(graphql_ir::Error::Internal(_)),
ExposeInternalErrors::Censor,
) => "internal error".into(),
(e, _) => e.to_string(),
};
// We are using the visibility of the error to determine if it is an internal error or not. We are assuming that
// if we are showing the error message to the user, it is something that they can fix on their end.
let is_internal = self.visibility() == ErrorVisibility::Internal;
GraphQLError {
message,View on GitHub (pinned to 724551b9ae)
Solutions
- Read the embedded String message; it usually names the unsupported construct or failing stage
- Try explaining a simplified version of the query to isolate which field/feature breaks explanation
- Execute the query normally — if it runs, the issue is explain-specific and can be reported upstream
- Update the engine to a version where explain supports the construct in question
Example fix
// before
POST /v1/graphql/explain { "query": "query { ... complex nested with @include }" }
// after
POST /v1/graphql/explain { "query": "query { ... simplified top-level field }" } Defensive patterns
Strategy: fallback
Validate before calling
// Guard explain-only features: reject explain requests for constructs
// your version can't explain before calling the endpoint:
if query.contains_directives(&["@include", "@skip"]) && mode == Explain {
return Err(ExplainUnsupported.into());
} Try / catch
let plan = match frontend.explain(&req).await {
Ok(p) => p,
Err(RequestError::ExplainError(msg)) => {
tracing::warn!(%msg, "explain failed; falling back to execution-only path");
return execution_only(&req).await;
}
Err(e) => return Err(e.into()),
}; Prevention
- Treat explain as best-effort: wrap it with a fallback to normal execution
- Pin the engine version and read release notes for explain-pipeline changes
- Report explain failures with the embedded message upstream — they often indicate planner gaps
When it happens
Trigger: Invoking the explain/plan-preview endpoint or generating an execution plan explanation for a query whose plan cannot be rendered — for example unsupported constructs in explain mode, IR-to-plan conversion problems during explanation, or downstream errors while formatting the plan for display.
Common situations: Running explain on queries using newer features not yet supported by the explain pipeline; explain endpoints hit during engine upgrades where plan formatting changed; internal errors in the planner surfacing only in explain mode.
Related errors
- Value did not match array type, was expecting {expected_type
- Value did not match object type, was expecting {expected_typ
- error from data source: {}
- subscription are not supported over HTTP
- parsing failed: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/296d7fc377b67a27.
Report an issue: GitHub.