{"record":{"id":"15ed298e52dc93b2","repo":"cube-js/cube","slug":"access-policy-condition-must-return-boolean-got","errorCode":null,"errorMessage":"Access policy condition must return boolean, got ${JSON.stringify(b)}","messagePattern":"Access policy condition must return boolean, got (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cubejs-server-core/src/core/CompilerApi.ts","lineNumber":403,"sourceCode":"  protected async getGroupsFromContext(context: Context): Promise<Set<string>> {\n    if (!this.contextToGroups) {\n      return new Set();\n    }\n    return new Set(await this.contextToGroups(context));\n  }\n\n  protected userHasGroup(userGroups: Set<string>, group: string | string[]): boolean {\n    if (Array.isArray(group)) {\n      return group.some(g => userGroups.has(g) || g === '*');\n    }\n    return userGroups.has(group) || group === '*';\n  }\n\n  protected policyMeetsConditions(evaluatedConditions?: any[]): boolean {\n    if (evaluatedConditions?.length) {\n      return evaluatedConditions.reduce((a, b) => {\n        if (typeof b !== 'boolean') {\n          throw new Error(`Access policy condition must return boolean, got ${JSON.stringify(b)}`);\n        }\n        return a && b;\n      });\n    }\n    return true;\n  }\n\n  protected async getCubesFromQuery(query: NormalizedQuery, context?: Context): Promise<Set<string>> {\n    const sql = await this.getSql(query, { requestId: context?.requestId });\n    return new Set(sql.memberNames.map(memberName => memberName.split('.')[0]));\n  }\n\n  protected hashRequestContext(context: Context): string {\n    if (!context.__hash) {\n      context.__hash = crypto.createHash('md5').update(JSON.stringify(context)).digest('hex');\n    }\n    return context.__hash;\n  }","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-server-core/src/core/CompilerApi.ts#L385-L421","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nconditions: [{ if: \"securityContext.tenantId\" }]\n// after\nconditions: [{ if: \"securityContext.tenantId != null\" }]","handlingStrategy":"validation","validationCode":"const results = (policy.conditions || []).map(c => compilers.cubeEvaluator.evaluateContextFunction(cube, c.if, context));\nif (results.some(r => typeof r !== 'boolean')) throw new Error('All access policy conditions must return strict booleans');","typeGuard":"const isBool = (v: unknown): v is boolean => typeof v === 'boolean';","tryCatchPattern":"try { const ok = policyMeetsConditions(evaluated); } catch (e) { if (/must return boolean/.test(e.message)) { console.error('Non-boolean policy condition', evaluated); } else throw e; }","preventionTips":["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"],"tags":["security","access-policy","validation"],"backgroundTag":"access-policy-condition-type","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}