{"record":{"id":"6b7493967d1cb7b6","repo":"apache/druid","slug":"expected-a-single-column-but-got-s-columns-ple","errorCode":null,"errorMessage":"Expected a single column but got [%s] columns. Please check broker logs for more information.","messagePattern":"Expected a single column but got \\[(.+?)\\] columns\\. Please check broker logs for more information\\.","errorType":"http","errorClass":"RE","httpStatus":500,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/sql/resources/SqlStatementResource.java","lineNumber":530,"sourceCode":"      return responseBuilder.build();\n    }\n    catch (Throwable e) {\n      // make sure to close yielder if anything happened before starting to serialize the response.\n      yielder0.close();\n      throw e;\n    }\n  }\n\n  private Response buildTaskResponse(Sequence<Object[]> sequence, AuthenticationResult authenticationResult)\n  {\n    List<Object[]> rows = sequence.toList();\n    int numRows = rows.size();\n    if (numRows != 1) {\n      throw new RE(\"Expected a single row but got [%d] rows. Please check broker logs for more information.\", numRows);\n    }\n    Object[] firstRow = rows.get(0);\n    if (firstRow == null || firstRow.length != 1) {\n      throw new RE(\n          \"Expected a single column but got [%s] columns. Please check broker logs for more information.\",\n          firstRow == null ? 0 : firstRow.length\n      );\n    }\n    String taskId = String.valueOf(firstRow[0]);\n\n    Optional<SqlStatementResult> statementResult = getStatementStatus(\n        taskId,\n        authenticationResult,\n        true,\n        Action.READ,\n        false\n    );\n\n    if (statementResult.isPresent()) {\n      return Response.status(Response.Status.OK).entity(statementResult.get()).build();\n    } else {\n      return buildNonOkResponse(","sourceCodeStart":512,"sourceCodeEnd":548,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/sql/resources/SqlStatementResource.java#L512-L548","documentation":"After confirming exactly one row, buildTaskResponse requires that row to have exactly one column containing the taskId. If the row is null or has a different column count, this RE is thrown. It protects the /sql/statements response contract: the task-status query must return a single taskId value.","triggerScenarios":"The single row returned by the internal task-status query has zero or multiple columns — e.g. a changed/incorrect internal SELECT for the ingestion task id, or an unexpected engine result schema after an upgrade or a custom query modification.","commonSituations":"Running a modified/patched Druid where the internal status query's projection changed; interacting with the statements API through a proxy that rewrites the request; mixed-version cluster where broker and MSQ engine disagree on the status row schema.","solutions":["Inspect broker logs for the internal task-status query and compare its select list to the expected single-column taskId projection.","Ensure all cluster nodes run the same Druid version (no mixed-version schema mismatch).","Remove any custom extensions/filters that could alter the status query, then retry the statements API call.","If persistent, file/check Druid issue tracker for regressions in SqlStatementResource."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// verify the status query response shape client-side before consuming\nObject[] row = rows.get(0);\nif (row == null || row.length != 1) {\n  throw new IllegalStateException(\"Unexpected task-status row shape, expected single taskId column\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  submitAsync(query);\n} catch (DruidException e) {\n  if (e.getMessage().contains(\"Expected a single column\")) {\n    upgradeOrAlignClusterVersions(); // schema mismatch between nodes\n  }\n  throw e;\n}","preventionTips":["Do not modify internal task-status queries in custom patches without updating SqlStatementResource expectations.","Run a homogeneous Druid version across brokers and MSQ engines.","Test async statements API after upgrades in staging."],"tags":["msq","rest-api","async-query","result-shape","schema-mismatch"],"backgroundTag":"unexpected-response-shape","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}