cube-js/cube · error · Error

Multi stage member '${multiStageMember}' lacks FROM clause i

Error message

Multi stage member '${multiStageMember}' lacks FROM clause in sub query: ${JSON.stringify(subQueryOptions)}

What it means

This error is thrown when a sub query created for a multi-stage member does not have a FROM clause. Cube checks each sub query produced by newSubQuery(): if subQuery.from is missing, it searches all sub query members for one flagged isMultiStage(); if found, it throws because multi-stage (rolled-up) members require an explicit FROM clause to be evaluated correctly.

Source

Thrown at packages/cubejs-schema-compiler/src/adapter/BaseQuery.js:1857

      memberToAlias: this.options.memberToAlias,
      from: fromSql && {
        sql: fromSql,
        alias: `${withQuery.alias}_join`,
      },
      // TODO condition should something else instead of rank
      multiStageQuery: !!withQuery.measures.find(d => {
        const { type } = this.newMeasure(d).definition();
        return type === 'rank' || CubeSymbols.isCalculatedMeasureType(type);
      }),
      disableExternalPreAggregations: true,
    };
    const subQuery = this.newSubQuery(subQueryOptions);

    if (!subQuery.from) {
      const allSubQueryMembers = R.flatten(subQuery.collectFromMembers(false, subQuery.collectMemberNamesFor.bind(subQuery), 'collectMemberNamesFor'));
      const multiStageMember = allSubQueryMembers.find(m => this.memberInstanceByPath(m).isMultiStage());
      if (multiStageMember) {
        throw new Error(`Multi stage member '${multiStageMember}' lacks FROM clause in sub query: ${JSON.stringify(subQueryOptions)}`);
      }
    }

    return {
      query: subQuery.evaluateSymbolSqlWithContext(
        () => subQuery.buildParamAnnotatedSql(),
        renderedReferenceContext,
      ),
      alias: withQuery.alias
    };
  }

  dimensionsJoinCondition(leftAlias, rightAlias) {
    const dimensionAliases = this.dimensionAliasNames();
    if (!dimensionAliases.length) {
      return '1 = 1';
    }
    return dimensionAliases

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Give the multi-stage member an explicit cube context so the sub query can resolve a FROM clause (e.g. define it in the cube that owns the underlying data, or set the cube in the sub query options).
  2. Rewrite the multi-stage member as a regular sub query measure (sql: ${...}.subQuery with a defined subQuery) instead of relying on implicit multi-stage rollup.
  3. If composing subQueryOptions manually, include a valid `from` (cube/join tree) in the options.
  4. Upgrade Cube — this validation has been refined over time; check release notes for multi-stage member fixes.

Example fix

// before (view member referencing multi-stage measure without cube context)
measures: {
  ratio: { type: 'number', sql: `${users.total} / NULLIF(${sessions.count}, 0)` }
}
// after (pin each member to its cube / use a defined sub query)
measures: {
  ratio: {
    type: 'number',
    sql: `${users.total} / NULLIF(${sessionsSubQuery.count}, 0)`,
    subQuery: true
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Before compiling, ensure multi-stage members live in cubes with resolvable context
function assertMultiStageHasContext(schema, memberPath) {
  const member = schema.memberByPath(memberPath);
  if (member && member.isMultiStage && member.isMultiStage() && !member.cube) {
    throw new Error(`Multi-stage member ${memberPath} must be defined within a cube to get a FROM clause`);
  }
}

Type guard

function isMultiStageMemberSafe(member) {
  return !member.isMultiStage || !member.isMultiStage() || Boolean(member.cube);
}

Try / catch

try {
  const result = await cube.query(query);
} catch (e) {
  if (/lacks FROM clause in sub query/.test(e.message)) {
    throw new Error('Schema error: give the multi-stage member an explicit cube context or rewrite as subQuery');
  }
  throw e;
}

Prevention

When it happens

Trigger: Defining a multi-stage (multi-fact / rolled-up) measure or dimension whose generated sub query options lack a FROM clause — typically when the multi-stage member is referenced inside a sub query definition (subQueryOptions) built without a base cube/join tree.

Common situations: Schema mistakes: referencing a multi-stage measure inside another measure's subQuery/sql, defining a multi-stage member in a view without specifying the underlying cube, or passing hand-crafted subQueryOptions that omit `from`.

Related errors


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