{"record":{"id":"72b4b2a1cd27a6ee","repo":"cube-js/cube","slug":"expressions-are-not-allowed-in-this-context","errorCode":null,"errorMessage":"Expressions are not allowed in this context","messagePattern":"Expressions are not allowed in this context","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cubejs-api-gateway/src/gateway.ts","lineNumber":1441,"sourceCode":"    const queryRewriteId = uuidv4();\n    this.log({\n      type: 'Query Rewrite',\n      queryRewriteId,\n      query\n    }, context);\n\n    const startTime = new Date().getTime();\n    const compilerApi = await this.getCompilerApi(context);\n\n    const queryNormalizationResult: Array<{\n      normalizedQuery: NormalizedQuery,\n      hasExpressionsInQuery: boolean\n    }> = queries.map((currentQuery) => {\n      const hasExpressionsInQuery = this.hasExpressionsInQuery(currentQuery);\n\n      if (hasExpressionsInQuery) {\n        if (!memberExpressions) {\n          throw new Error('Expressions are not allowed in this context');\n        }\n\n        currentQuery = this.parseMemberExpressionsInQuery(currentQuery);\n      }\n\n      if ((currentQuery as any).maskedMembers) {\n        throw new UserError('maskedMembers cannot be provided in the query');\n      }\n\n      return {\n        normalizedQuery: (normalizeQuery(currentQuery, persistent, cacheMode)),\n        hasExpressionsInQuery\n      };\n    });\n\n    let normalizedQueries: NormalizedQuery[] = await Promise.all(\n      queryNormalizationResult.map(\n        async ({ normalizedQuery, hasExpressionsInQuery }) => {","sourceCodeStart":1423,"sourceCodeEnd":1459,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-api-gateway/src/gateway.ts#L1423-L1459","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Remove raw member expressions from the query and use pre-defined calculated members/segments in the data model instead.","If using the SQL API programmatically, enable the member-expressions option for the request (pass `memberExpressions: true` in the QueryRequest so `getNormalizedQueries` accepts them).","Move the expression logic into the schema (a calculated member or SQL expression in the cube definition) so clients send only plain member references.","If the query unexpectedly contains expressions, inspect `filters`/`measures`/`segments` for expression objects (keys like `expression` or function syntax) and replace them.","Check your Cube version: expression handling and flags have changed across releases; align client query generation with the server's supported syntax."],"exampleFix":"// before — expression in the query filter\n{ \"measures\": [\"Orders.count\"], \"filters\": [{ \"expression\": \"{Orders}.revenue > 100\" }] }\n\n// after — expression lives in the data model; query uses the member\n// schema: revenueOver100: { sql: `${revenue} > 100`, type: 'boolean' }\n{ \"measures\": [\"Orders.count\"], \"filters\": [{ \"member\": \"Orders.revenueOver100\", \"operator\": \"equals\", \"values\": [\"true\"] }] }","handlingStrategy":"validation","validationCode":"function containsMemberExpressions(query) {\n  const exprKeys = ['expression'];\n  const sections = ['measures', 'dimensions', 'segments', 'filters'];\n  return sections.some(section =>\n    (query?.[section] || []).some(item =>\n      exprKeys.some(k => k in item) || typeof item === 'string' && /\\{\\s*\\w+\\s*\\}\\./.test(item)\n    )\n  );\n}\n// call before invoking the SQL path; if true, either enable memberExpressions or rewrite the query","typeGuard":"type PlainQuery = { measures: string[]; dimensions: string[]; filters?: { member: string; operator: string; values: string[] }[] };\nfunction isPlainMemberQuery(q: unknown): q is PlainQuery {\n  const sections = ['measures', 'dimensions', 'segments', 'filters'];\n  return !!q && typeof q === 'object' &&\n    !sections.some(s =>\n      Array.isArray((q as any)[s]) &&\n      (q as any)[s].some((i: any) => i && typeof i === 'object' && 'expression' in i)\n    );\n}","tryCatchPattern":"try {\n  const sql = await sqlApi.query(query);\n} catch (e) {\n  if (String(e.message).includes('Expressions are not allowed in this context')) {\n    // query contains member expressions but the path has them disabled;\n    // rewrite with named members or enable memberExpressions for the request\n    console.error('Member expressions found in query:', JSON.stringify(query));\n  }\n}","preventionTips":["Push expression logic into calculated members/segments in the data model instead of inline query expressions.","Only send expression-containing queries through API paths that explicitly enable member expressions (e.g., the SQL API with the flag on).","Add a client-side lint that scans filters/measures/segments for expression objects before submission.","Keep client query generation in sync with your server Cube version's expression support."],"tags":["member-expressions","query-processing","sql-api","validation"],"backgroundTag":"member-expressions-not-allowed","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}