cube-js/cube · error · Error

Access policy condition must return boolean, got ${JSON.stri

Error message

Access policy condition must return boolean, got ${JSON.stringify(b)}

What it means

Access policy 'if' conditions are evaluated against the security context and every condition must reduce to a strict boolean. policyMeetsConditions reduces the evaluated conditions with && and throws if any evaluated value is not exactly boolean (e.g. undefined, string, object).

Source

Thrown at packages/cubejs-server-core/src/core/CompilerApi.ts:403

  protected async getGroupsFromContext(context: Context): Promise<Set<string>> {
    if (!this.contextToGroups) {
      return new Set();
    }
    return new Set(await this.contextToGroups(context));
  }

  protected userHasGroup(userGroups: Set<string>, group: string | string[]): boolean {
    if (Array.isArray(group)) {
      return group.some(g => userGroups.has(g) || g === '*');
    }
    return userGroups.has(group) || group === '*';
  }

  protected policyMeetsConditions(evaluatedConditions?: any[]): boolean {
    if (evaluatedConditions?.length) {
      return evaluatedConditions.reduce((a, b) => {
        if (typeof b !== 'boolean') {
          throw new Error(`Access policy condition must return boolean, got ${JSON.stringify(b)}`);
        }
        return a && b;
      });
    }
    return true;
  }

  protected async getCubesFromQuery(query: NormalizedQuery, context?: Context): Promise<Set<string>> {
    const sql = await this.getSql(query, { requestId: context?.requestId });
    return new Set(sql.memberNames.map(memberName => memberName.split('.')[0]));
  }

  protected hashRequestContext(context: Context): string {
    if (!context.__hash) {
      context.__hash = crypto.createHash('md5').update(JSON.stringify(context)).digest('hex');
    }
    return context.__hash;
  }

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Make every condition return an explicit boolean, e.g. a comparison (===) rather than a bare value
  2. Coerce with Boolean(...) or !! only if the semantics are intended
  3. Log the evaluated conditions to find which one is non-boolean
  4. Fix the securityContext so referenced fields exist

Example fix

// before
conditions: [{ if: "securityContext.tenantId" }]
// after
conditions: [{ if: "securityContext.tenantId != null" }]
Defensive patterns

Strategy: validation

Validate before calling

const results = (policy.conditions || []).map(c => compilers.cubeEvaluator.evaluateContextFunction(cube, c.if, context));
if (results.some(r => typeof r !== 'boolean')) throw new Error('All access policy conditions must return strict booleans');

Type guard

const isBool = (v: unknown): v is boolean => typeof v === 'boolean';

Try / catch

try { const ok = policyMeetsConditions(evaluated); } catch (e) { if (/must return boolean/.test(e.message)) { console.error('Non-boolean policy condition', evaluated); } else throw e; }

Prevention

When it happens

Trigger: A policy condition expression (condition.if) returns undefined because a referenced context field is missing, or the expression itself returns a truthy non-boolean (string, number, array).

Common situations: securityContext field renamed so lookups become undefined; writing conditions like "if: "${securityContext.tenant}"" returning a string instead of a comparison; JS-based policies returning objects.

Related errors


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