{"record":{"id":"0e2d07ccf7b6ef07","repo":"googleapis/mcp-toolbox","slug":"dry-run-produced-no-execution-plan","errorCode":null,"errorMessage":"dry-run produced no execution plan","messagePattern":"dry-run produced no execution plan","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/arcadedb/arcadedb.go","lineNumber":151,"sourceCode":"\t\treturn nil, fmt.Errorf(\"this tool is read-only and cannot execute write queries\")\n\t}\n\n\tif dryRun {\n\t\tcypherStr = \"EXPLAIN \" + cypherStr\n\t}\n\n\tconfig := neo4j.ExecuteQueryWithDatabase(s.ArcadeDBDatabase())\n\tresults, err := neo4j.ExecuteQuery[*neo4j.EagerResult](ctx, s.ArcadeDBDriver(), cypherStr, params,\n\t\tneo4j.EagerResultTransformer, config)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to execute query: %w\", err)\n\t}\n\n\tif dryRun {\n\t\tsummary := results.Summary\n\t\tplan := summary.Plan()\n\t\tif plan == nil {\n\t\t\treturn nil, fmt.Errorf(\"dry-run produced no execution plan\")\n\t\t}\n\n\t\tnode, incomplete, operatorCount := buildPlanNode(plan)\n\t\tif operatorCount == 0 {\n\t\t\treturn nil, fmt.Errorf(\"dry-run produced an empty execution plan\")\n\t\t}\n\n\t\texecPlan := map[string]any{\n\t\t\t\"queryType\":     cf.Type.String(),\n\t\t\t\"statementType\": summary.QueryType(),\n\t\t}\n\t\tfor k, v := range node {\n\t\t\texecPlan[k] = v\n\t\t}\n\t\tif incomplete {\n\t\t\texecPlan[\"plan_incomplete\"] = true\n\t\t\texecPlan[\"warning\"] = \"Execution plan appears partial; server may not provide complete EXPLAIN details for this query/version.\"\n\t\t}","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/arcadedb/arcadedb.go#L133-L169","documentation":"In dry-run mode, RunCypher prefixes the query with EXPLAIN and expects the result summary to contain an execution plan. This error means the server returned a summary whose Plan() is nil — no plan object was produced — so the dry-run contract cannot be honored. It indicates the server did not return plan metadata for the EXPLAIN query.","triggerScenarios":"Calling RunCypher with dryRun=true when the backend (ArcadeDB via the Neo4j-compatible Bolt layer) returns a summary without a plan, e.g. the EXPLAIN prefix is unsupported for that statement type or the server omits plan data.","commonSituations":"Using dry-run against an ArcadeDB version or query type that doesn't emit plan summaries; statements the backend executes without planning metadata; protocol/compatibility mismatches between driver and server versions.","solutions":["Retry without dry-run to execute the query normally.","Upgrade the ArcadeDB server to a version whose Bolt layer returns EXPLAIN plans for this query type.","Check that the query type is one the backend supports explaining (avoid utility/management statements).","Verify driver/server protocol compatibility (neo4j Go driver version vs ArcadeDB Bolt version)."],"exampleFix":"// before\ndryRun: true, query: \"CALL db.labels()\"\n// after: execute directly if the backend cannot explain it\ndryRun: false, query: \"CALL db.labels()\"","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"plan := results.Summary.Plan()\nif plan == nil {\n    // fall back to executing the query without dry-run, or surface a clear message\n    return executeWithoutDryRun(ctx, cypher)\n}","preventionTips":["Only use dry-run for query types known to produce EXPLAIN plans on your server version.","Test dry-run support per query type when upgrading ArcadeDB.","Keep the Neo4j-compatible Bolt layer and driver versions aligned.","Provide a non-dry-run fallback path in callers that depend on plan output."],"tags":["arcadedb","dry-run","execution-plan","compatibility"],"backgroundTag":"missing-execution-plan","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}