googleapis/mcp-toolbox · error
unable to explain query: %w
Error message
unable to explain query: %w
What it means
This error wraps the underlying Redis-protocol failure returned when issuing a raw GRAPH.EXPLAIN command to a FalkorDB server during a dry-run query. The source bypasses falkordb-go's ExecutionPlan parser (which cannot handle the raw array of plan lines) by calling s.Client.Conn.Do directly, so any transport, auth, or server-side command error surfaces here.
Source
Thrown at internal/sources/falkordb/falkordb.go:177
}
// RunQuery executes a Cypher query against a graph in the FalkorDB instance.
// An empty graphName targets the source's default graph. readOnly queries are
// dispatched as GRAPH.RO_QUERY, so the server itself rejects write operations.
// dryRun returns the GRAPH.EXPLAIN execution plan without running the query.
func (s *Source) RunQuery(ctx context.Context, graphName, cypherStr string, params map[string]any, readOnly, dryRun bool) (any, error) {
if graphName == "" {
graphName = s.Graph
}
graph := s.Client.SelectGraph(graphName)
if dryRun {
// GRAPH.EXPLAIN replies with an array of plan lines, which
// falkordb-go's ExecutionPlan does not handle; issue the command
// directly instead.
plan, err := s.Client.Conn.Do(ctx, "GRAPH.EXPLAIN", graphName, cypherStr).StringSlice()
if err != nil {
return nil, fmt.Errorf("unable to explain query: %w", err)
}
return map[string]any{"plan": plan}, nil
}
var opts *falkordb.QueryOptions
if s.QueryTimeoutMs > 0 {
opts = falkordb.NewQueryOptions().SetTimeout(s.QueryTimeoutMs)
}
var results *falkordb.QueryResult
var err error
if readOnly {
results, err = graph.ROQuery(cypherStr, params, opts)
} else {
results, err = graph.Query(cypherStr, params, opts)
}
if err != nil {
return nil, fmt.Errorf("unable to execute query: %w", err)View on GitHub (pinned to 8cc6e09de2)
Solutions
- Verify the FalkorDB server is reachable and the graph module is loaded (run GRAPH.QUERY or PING first)
- Check graphName exists (GRAPH.LIST) and the Cypher string is non-empty
- Upgrade FalkorDB/RedisGraph to a version that supports GRAPH.EXPLAIN
- Inspect the wrapped error with errors.Unwrap/log %v for the concrete redis failure (auth, timeout, decode)
Example fix
// before
plan, err := s.Client.Conn.Do(ctx, "GRAPH.EXPLAIN", graphName, cypherStr).StringSlice()
if err != nil {
return nil, fmt.Errorf("unable to explain query: %w", err)
}
// after
plan, err := s.Client.Conn.Do(ctx, "GRAPH.EXPLAIN", graphName, cypherStr).StringSlice()
if err != nil {
return nil, fmt.Errorf("unable to explain query (graph=%s): %w", graphName, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before dryRun, check module availability
res := client.Do(ctx, "COMMAND", "INFO")
if err := res.Err(); err != nil { return err }
// or verify graph exists
exists, _ := client.Do(ctx, "GRAPH.LIST").StringSlice() Type guard
func isRedisError(err error) bool {
var rErr *redis.Error
return errors.As(err, &rErr)
} Try / catch
plan, err := s.Client.Conn.Do(ctx, "GRAPH.EXPLAIN", graph, cypher).StringSlice()
if err != nil {
var rErr redis.Error
if errors.As(err, &rErr) && strings.Contains(err.Error(), "unknown command") {
// fall back: run query with timeout 0 or surface module-missing guidance
}
return nil, fmt.Errorf("dry-run explain failed: %w", err)
} Prevention
- Confirm FalkorDB module is loaded before enabling dry-run tooling
- Keep client library and server versions compatible (GRAPH.EXPLAIN reply shape changed across versions)
- Include graph name in wrapped errors for faster triage
- Smoke-test GRAPH.EXPLAIN in CI against the same server image used in production
When it happens
Trigger: RunQuery invoked with dryRun=true while the GRAPH.EXPLAIN command fails: server unreachable, connection closed, wrong graph name, unsupported/renamed GRAPH.EXPLAIN command on older RedisGraph versions, or a non-string reply type that StringSlice() cannot decode.
Common situations: Container/network misconfig pointing at the wrong port; FalkorDB module not loaded so GRAPH.EXPLAIN returns unknown-command; typo in graphName; TLS/auth mismatch; running against plain Redis without the graph module.
Related errors
- dry-run produced no execution plan
- dry-run produced an empty execution plan
- tls.insecureSkipVerify is set on source %q but tls.enabled i
- unable to get logger from ctx: %s
- unable to create client: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/bf90a937744dd5be.
Report an issue: GitHub.