{"record":{"id":"7ab4535d8fb1e72c","repo":"cube-js/cube","slug":"queryexecution-queryexecution-status-statechan","errorCode":null,"errorMessage":"${queryExecution.QueryExecution?.Status?.StateChangeReason}","messagePattern":"\\$\\{queryExecution\\.QueryExecution\\?\\.Status\\?\\.StateChangeReason\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cubejs-athena-driver/src/AthenaDriver.ts","lineNumber":614,"sourceCode":"        OutputLocation: this.config.S3OutputLocation\n      },\n      ...(this.config.catalog || this.config.database ? {\n        QueryExecutionContext: {\n          Catalog: this.config.catalog,\n          Database: this.config.database\n        }\n      } : {})\n    };\n    const { QueryExecutionId } = await this.athena.startQueryExecution(request);\n    return { QueryExecutionId: checkNonNullable('StartQueryExecution', QueryExecutionId) };\n  }\n\n  protected async checkStatus(qid: AthenaQueryId): Promise<boolean> {\n    const queryExecution = await this.athena.getQueryExecution(qid);\n\n    const status = queryExecution.QueryExecution?.Status?.State;\n    if (status === 'FAILED') {\n      throw new Error(queryExecution.QueryExecution?.Status?.StateChangeReason);\n    }\n\n    if (status === 'CANCELLED') {\n      throw new Error('Query has been cancelled');\n    }\n\n    return status === 'SUCCEEDED';\n  }\n\n  protected async waitForSuccess(qid: AthenaQueryId, isCancelled?: () => boolean): Promise<void> {\n    const startedTime = Date.now();\n    for (let i = 0; Date.now() - startedTime <= this.config.pollTimeout; i++) {\n      if (isCancelled?.()) {\n        throw new Error('Query was cancelled');\n      }\n      if (await this.checkStatus(qid)) {\n        return;\n      }","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-athena-driver/src/AthenaDriver.ts#L596-L632","documentation":"The Athena driver polls each query via getQueryExecution in checkStatus. When AWS reports the query state as FAILED, the driver throws an Error whose message is AWS's StateChangeReason — the raw reason Athena gives for the failure (e.g. syntax error, table not found, insufficient permissions, S3 output location issues). This is a pass-through of the Athena-side failure, not a driver bug.","triggerScenarios":"Any query started with startQuery (unloadWithSql, unloadWithTable, queryColumnTypes, schema/information-schema queries) whose Athena QueryExecution transitions to FAILED during waitForSuccess polling — e.g. invalid SQL, missing Glue table, wrong S3OutputLocation, or IAM permission denial.","commonSituations":"Typo in schema/table names in Cube data models; S3 output bucket missing or not writable by the execution role; Glue catalog permission errors; Athena engine limit errors (e.g. too many concurrent queries); workgroup query limits exceeded.","solutions":["Read the error message itself — it is Athena's StateChangeReason and names the root cause; fix the underlying SQL/permission/S3 issue it describes.","Verify S3OutputLocation points to an existing s3:// bucket/path writable by the Athena service role.","Check IAM permissions for the Athena workgroup role on Glue catalog/database/table and the S3 output location.","Run the failing query directly in the Athena console with the same workgroup/catalog/database to reproduce and debug."],"exampleFix":"// before: wrong S3OutputLocation\nnew AthenaDriver({ S3OutputLocation: 's3://my-bucket' }); // role lacks s3:PutObject\n// after\nnew AthenaDriver({ S3OutputLocation: 's3://my-bucket/athena-results/', workGroup: 'primary' }); // policy grants s3:PutObject on that prefix","handlingStrategy":"try-catch","validationCode":"// Pre-check Athena workgroup and S3 output location accessibility\nimport { AthenaClient, GetWorkGroupCommand } from '@aws-sdk/client-athena';\nconst athena = new AthenaClient({ region });\nawait athena.send(new GetWorkGroupCommand({ WorkGroup: workGroup })); // throws early if misconfigured","typeGuard":"function hasStateChangeReason(e: unknown): e is Error & { message: string } {\n  return e instanceof Error && typeof e.message === 'string' && e.message.length > 0;\n}","tryCatchPattern":"try {\n  await driver.query(sql, values);\n} catch (e) {\n  if (e instanceof Error && /S3OutputLocation|Access Denied|SYNTAX_ERROR|TABLE_NOT_FOUND/i.test(e.message)) {\n    // Athena StateChangeReason surfaced: fix SQL/IAM/S3 per message\n  }\n  throw e;\n}","preventionTips":["Grant the Athena role s3:PutObject on the S3OutputLocation prefix and Glue read access to all queried databases/tables.","Test complex model SQL directly in the Athena console before wiring it into Cube.","Pin a valid workgroup and check its query limits in the AWS console."],"tags":["aws","athena","query-failed","sql"],"backgroundTag":"athena-query-failed","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}