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
- Make every condition return an explicit boolean, e.g. a comparison (===) rather than a bare value
- Coerce with Boolean(...) or !! only if the semantics are intended
- Log the evaluated conditions to find which one is non-boolean
- 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
- Write conditions as comparisons (===, != null) not bare lookups
- Validate securityContext shape before evaluation
- Unit-test each policy condition against sample contexts
- Avoid JS policies that return objects/strings
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
- Access policy cannot have both 'group' and 'groups' properti
- Can't parse date: '${from}'
- Can't parse date: '${to}'
- Can't parse date: '${dateString}'
- Invalid Job query format: ${error.message || error.toString(
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/15ed298e52dc93b2.
Report an issue: GitHub.