cube-js/cube · error

${queryExecution.QueryExecution?.Status?.StateChangeReason}

Error message

${queryExecution.QueryExecution?.Status?.StateChangeReason}

What it means

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.

Source

Thrown at packages/cubejs-athena-driver/src/AthenaDriver.ts:614

        OutputLocation: this.config.S3OutputLocation
      },
      ...(this.config.catalog || this.config.database ? {
        QueryExecutionContext: {
          Catalog: this.config.catalog,
          Database: this.config.database
        }
      } : {})
    };
    const { QueryExecutionId } = await this.athena.startQueryExecution(request);
    return { QueryExecutionId: checkNonNullable('StartQueryExecution', QueryExecutionId) };
  }

  protected async checkStatus(qid: AthenaQueryId): Promise<boolean> {
    const queryExecution = await this.athena.getQueryExecution(qid);

    const status = queryExecution.QueryExecution?.Status?.State;
    if (status === 'FAILED') {
      throw new Error(queryExecution.QueryExecution?.Status?.StateChangeReason);
    }

    if (status === 'CANCELLED') {
      throw new Error('Query has been cancelled');
    }

    return status === 'SUCCEEDED';
  }

  protected async waitForSuccess(qid: AthenaQueryId, isCancelled?: () => boolean): Promise<void> {
    const startedTime = Date.now();
    for (let i = 0; Date.now() - startedTime <= this.config.pollTimeout; i++) {
      if (isCancelled?.()) {
        throw new Error('Query was cancelled');
      }
      if (await this.checkStatus(qid)) {
        return;
      }

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Read the error message itself — it is Athena's StateChangeReason and names the root cause; fix the underlying SQL/permission/S3 issue it describes.
  2. Verify S3OutputLocation points to an existing s3:// bucket/path writable by the Athena service role.
  3. Check IAM permissions for the Athena workgroup role on Glue catalog/database/table and the S3 output location.
  4. Run the failing query directly in the Athena console with the same workgroup/catalog/database to reproduce and debug.

Example fix

// before: wrong S3OutputLocation
new AthenaDriver({ S3OutputLocation: 's3://my-bucket' }); // role lacks s3:PutObject
// after
new AthenaDriver({ S3OutputLocation: 's3://my-bucket/athena-results/', workGroup: 'primary' }); // policy grants s3:PutObject on that prefix
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check Athena workgroup and S3 output location accessibility
import { AthenaClient, GetWorkGroupCommand } from '@aws-sdk/client-athena';
const athena = new AthenaClient({ region });
await athena.send(new GetWorkGroupCommand({ WorkGroup: workGroup })); // throws early if misconfigured

Type guard

function hasStateChangeReason(e: unknown): e is Error & { message: string } {
  return e instanceof Error && typeof e.message === 'string' && e.message.length > 0;
}

Try / catch

try {
  await driver.query(sql, values);
} catch (e) {
  if (e instanceof Error && /S3OutputLocation|Access Denied|SYNTAX_ERROR|TABLE_NOT_FOUND/i.test(e.message)) {
    // Athena StateChangeReason surfaced: fix SQL/IAM/S3 per message
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/7ab4535d8fb1e72c. Report an issue: GitHub.