{"record":{"id":"b69295e62ede054b","repo":"cube-js/cube","slug":"filter-for-column-is-required","errorCode":null,"errorMessage":"Filter for ${column} is required","messagePattern":"Filter for (.+?) is required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/adapter/MemberSqlTemplateCompiler.js","lineNumber":308,"sourceCode":"    if (param.kind === 'string') {\n      const ph = recordSecurityValue(param.value, state);\n      if (typeof column === 'function') return column(ph);\n      if (typeof column === 'string') return `${column} = ${ph}`;\n      return '';\n    }\n    if (param.kind === 'vec') {\n      if (param.values.length === 0) {\n        if (typeof column === 'function') return column([]);\n        return '1 = 0';\n      }\n      const phs = param.values.map(v => recordSecurityValue(v, state));\n      if (typeof column === 'function') return column(phs);\n      if (typeof column === 'string') return `${column} IN (${phs.join(', ')})`;\n      return '';\n    }\n    // none\n    if (required) {\n      throw new Error(`Filter for ${column} is required`);\n    }\n    return '1 = 1';\n  };\n}\n\nfunction securityToStringFn(value, state) {\n  const values = coerceToStringValue(value);\n  return () => {\n    if (values === null) return '';\n    return values.map(v => recordSecurityValue(v, state)).join(',');\n  };\n}\n\nfunction securityContextProxy(value, state) {\n  return new Proxy({}, {\n    get(_t, prop) {\n      if (typeof prop !== 'string') return undefined;\n      // Methods coerce the current value lazily — only on access, so reading a","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/adapter/MemberSqlTemplateCompiler.js#L290-L326","documentation":"securityFilterFn builds a required 'column IN (...)' filter from security-context values. When no valid values were produced (the coerced kind was 'none' — e.g. 0, NaN, false, null, or an empty array) and the filter was declared required, the compiler refuses to emit a permissive '1 = 1' and throws instead, so the query cannot silently return all rows.","triggerScenarios":"A required security filter (e.g. { filters: [ { member: 'Cubes.tenantId', operator: 'equals', ... requireFilter: true } ] } via filterable cube params) receives a falsy security-context value such as 0, false, NaN, undefined, or an empty list, so no IN clause values exist.","commonSituations":"JWT token missing the expected claim so the value resolves to undefined; tenant id legitimately equals 0 but the coercion treats 0 as 'none'; misconfigured securityContext path so the value never materializes.","solutions":["Verify the security context actually contains the claim the filter references and that it is a valid non-falsy number/boolean.","Use the securityContext entry directly (e.g. securityFilters or ctx['securityContext'].tenantId) instead of a hard-coded 0/false value.","Make the filter optional if an empty result ('1 = 1') is acceptable by setting required to false in the template call.","Fix upstream auth so every token carries the required tenant/organization claim before queries compile."],"exampleFix":"// before\nthrowing setup: securityContext value { tenantId: 0 } with required filter\n// after\nsecurityContext: ctx => ({ tenantId: ctx.tenant_id ?? -1 }) // ensure a real numeric value is always present","handlingStrategy":"validation","validationCode":"const val = securityContext?.tenantId;\nif (val === undefined || val === null || val === 0 || val === false || Number.isNaN(val)) {\n  throw new Error(`Required security filter value missing/falsy for tenantId: ${JSON.stringify(val)}`);\n}","typeGuard":"const hasRequiredFilterValue = (v: unknown): v is number | true => v === true || (typeof v === 'number' && v !== 0 && !Number.isNaN(v));","tryCatchPattern":"try { await cube.query(...); } catch (e) { if (/Filter for .* is required/.test(e.message)) { // reject request: security context claim missing\n  return res.status(403).json({ error: 'Missing tenant claim in security context' }); } throw e; }","preventionTips":["Guarantee JWT middleware injects the required claims before query execution","Avoid 0/false as tenant identifiers (use 1-based or string ids elsewhere)","Log the securityContext object when this error occurs to spot missing claims","Mark filters required:false only when returning all rows is genuinely acceptable"],"tags":["security-context","required-filter","schema-compiler"],"backgroundTag":"missing-security-context-filter-value","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}