cube-js/cube · error · Error

Invalid param for security context

Error message

Invalid param for security context

What it means

coerceScalarToString converts security context values (from securityContext claims used in member sql via security_context()) to strings; it only accepts string, number, and boolean. Any other type (null, undefined, object, array) triggers this Error.

Source

Thrown at packages/cubejs-schema-compiler/src/adapter/MemberSqlTemplateCompiler.js:252

    const filterParams = args.map(arg => {
      if (!arg || typeof arg.__member === 'undefined') {
        throw new Error('FILTER_GROUP expects FILTER_PARAMS args to be passed.');
      }
      return arg.__member;
    });
    const index = state.target.filterGroups.length;
    state.target.filterGroups.push({ filterParams });
    return placeholder(FILTER_GROUP_PREFIX, index);
  };
}

// ---- SECURITY_CONTEXT ------------------------------------------------------

function coerceScalarToString(value) {
  if (typeof value === 'string') return value;
  if (typeof value === 'number') return `${value}`;
  if (typeof value === 'boolean') return `${value}`;
  throw new Error('Invalid param for security context');
}

// Coercion used by `.filter()` — falsy scalars collapse to "no value".
function coerceFilterValue(value) {
  if (value === undefined || value === null) return { kind: 'none' };
  if (Array.isArray(value)) {
    return { kind: 'vec', values: value.map(coerceScalarToString) };
  }
  if (typeof value === 'string') {
    return value === '' ? { kind: 'none' } : { kind: 'string', value };
  }
  if (typeof value === 'number') {
    return value === 0 || Number.isNaN(value) ? { kind: 'none' } : { kind: 'string', value: `${value}` };
  }
  if (typeof value === 'boolean') {
    return value ? { kind: 'string', value: 'true' } : { kind: 'none' };
  }
  throw new Error('Invalid param for security context');

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Ensure the JWT includes the claim referenced in security_context() as a scalar string/number/boolean.
  2. Update token issuance to serialize the claim value (e.g. use user_id string instead of nested object).
  3. Provide a fallback default in the schema (e.g. `${FILTER_PARAMS...}` or COALESCE-style default) or validate context in checkAuth/dataSource.

Example fix

// before (token payload)
{ securityContext: { tenant: { id: 42 } } } // object claim
// after
{ securityContext: { tenantId: '42' } }
Defensive patterns

Strategy: validation

Validate before calling

function ensureScalar(v) {
  if (!['string', 'number', 'boolean'].includes(typeof v) || v === null) {
    throw new Error('securityContext claims must be string|number|boolean');
  }
}

Type guard

function isScalarClaim(v) {
  return typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean';
}

Try / catch

try { await cube.load(q) } catch (e) { if (/Invalid param for security context/.test(e.message)) { /* fix JWT claims or supply default context */ } else throw e; }

Prevention

When it happens

Trigger: A JWT security context claim used in a data model (security_context(key)) resolves to null/undefined because the claim is absent, or is an object/array rather than a scalar.

Common situations: Tokens issued without the expected claim; claims encoded as nested objects (e.g. `{ id: 1 }` instead of a scalar user id); multi-tenant setups where some tenants lack the claim.

Related errors


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