cube-js/cube · error

Expressions are not allowed in this context

Error message

Expressions are not allowed in this context

What it means

During query normalization, the gateway detects whether a query contains raw member expressions (SQL-like expressions referencing members, e.g. `{ "expression": "SUM({events}.revenue)" }` style filters/measures). Member expressions are only supported in specific code paths — notably the SQL API (`/sql`) when it is invoked with `memberExpressions: true`. If expressions are found in a context that didn't opt into them, this plain `Error` is thrown before any SQL is generated.

Source

Thrown at packages/cubejs-api-gateway/src/gateway.ts:1441

    const queryRewriteId = uuidv4();
    this.log({
      type: 'Query Rewrite',
      queryRewriteId,
      query
    }, context);

    const startTime = new Date().getTime();
    const compilerApi = await this.getCompilerApi(context);

    const queryNormalizationResult: Array<{
      normalizedQuery: NormalizedQuery,
      hasExpressionsInQuery: boolean
    }> = queries.map((currentQuery) => {
      const hasExpressionsInQuery = this.hasExpressionsInQuery(currentQuery);

      if (hasExpressionsInQuery) {
        if (!memberExpressions) {
          throw new Error('Expressions are not allowed in this context');
        }

        currentQuery = this.parseMemberExpressionsInQuery(currentQuery);
      }

      if ((currentQuery as any).maskedMembers) {
        throw new UserError('maskedMembers cannot be provided in the query');
      }

      return {
        normalizedQuery: (normalizeQuery(currentQuery, persistent, cacheMode)),
        hasExpressionsInQuery
      };
    });

    let normalizedQueries: NormalizedQuery[] = await Promise.all(
      queryNormalizationResult.map(
        async ({ normalizedQuery, hasExpressionsInQuery }) => {

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Remove raw member expressions from the query and use pre-defined calculated members/segments in the data model instead.
  2. If using the SQL API programmatically, enable the member-expressions option for the request (pass `memberExpressions: true` in the QueryRequest so `getNormalizedQueries` accepts them).
  3. Move the expression logic into the schema (a calculated member or SQL expression in the cube definition) so clients send only plain member references.
  4. If the query unexpectedly contains expressions, inspect `filters`/`measures`/`segments` for expression objects (keys like `expression` or function syntax) and replace them.
  5. Check your Cube version: expression handling and flags have changed across releases; align client query generation with the server's supported syntax.

Example fix

// before — expression in the query filter
{ "measures": ["Orders.count"], "filters": [{ "expression": "{Orders}.revenue > 100" }] }

// after — expression lives in the data model; query uses the member
// schema: revenueOver100: { sql: `${revenue} > 100`, type: 'boolean' }
{ "measures": ["Orders.count"], "filters": [{ "member": "Orders.revenueOver100", "operator": "equals", "values": ["true"] }] }
Defensive patterns

Strategy: validation

Validate before calling

function containsMemberExpressions(query) {
  const exprKeys = ['expression'];
  const sections = ['measures', 'dimensions', 'segments', 'filters'];
  return sections.some(section =>
    (query?.[section] || []).some(item =>
      exprKeys.some(k => k in item) || typeof item === 'string' && /\{\s*\w+\s*\}\./.test(item)
    )
  );
}
// call before invoking the SQL path; if true, either enable memberExpressions or rewrite the query

Type guard

type PlainQuery = { measures: string[]; dimensions: string[]; filters?: { member: string; operator: string; values: string[] }[] };
function isPlainMemberQuery(q: unknown): q is PlainQuery {
  const sections = ['measures', 'dimensions', 'segments', 'filters'];
  return !!q && typeof q === 'object' &&
    !sections.some(s =>
      Array.isArray((q as any)[s]) &&
      (q as any)[s].some((i: any) => i && typeof i === 'object' && 'expression' in i)
    );
}

Try / catch

try {
  const sql = await sqlApi.query(query);
} catch (e) {
  if (String(e.message).includes('Expressions are not allowed in this context')) {
    // query contains member expressions but the path has them disabled;
    // rewrite with named members or enable memberExpressions for the request
    console.error('Member expressions found in query:', JSON.stringify(query));
  }
}

Prevention

When it happens

Trigger: Sending a query containing member-expression syntax (functions like `concat`, `filter` groups with raw expressions, or member expression objects/strings in measures/dimensions/segments/filters) through an API path that calls `getNormalizedQueries` without `memberExpressions=true` — e.g., certain internal SQL-API invocations (sql-server / SQL interface usage at gateway.ts:1562 depends on the `memberExpressions` request flag) or other endpoints that reuse normalization with the flag left at its default `false`.

Common situations: Using the SQL API against queries generated by a frontend that embeds expression members; a BI tool pushing expression-containing queries through a Cube SQL interface path that doesn't enable member expressions; version upgrades where expression support moved behind an explicit flag; mixing the REST data query API (which handles expressions differently) with the SQL API expectations.

Related errors


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