nexu-io/open-design · error · RangeError

OD_CRITIQUE_FALLBACK_POLICY must be one of ${FALLBACK_POLICI

Error message

OD_CRITIQUE_FALLBACK_POLICY must be one of ${FALLBACK_POLICIES.join(', ')}, got "${raw}"

What it means

Thrown by parseFallbackPolicy() (used by loadCritiqueConfigFromEnv for OD_CRITIQUE_FALLBACK_POLICY) as a RangeError when the value is set but not one of the allowed policies in FALLBACK_POLICIES (the canonical list from @open-design/contracts/critique). ${raw} is the offending input. The fallback policy controls what happens when a critique panelist degrades or fails, so an unknown value cannot be silently coerced.

Source

Thrown at apps/daemon/src/critique/config.ts:85

  const n = Number(raw);
  if (!Number.isFinite(n) || n < 0) {
    throw new RangeError(
      `${key} must be a non-negative finite number, got "${raw}"`,
    );
  }
  return n;
}

function parseFallbackPolicy(
  raw: string | undefined,
  fallback: CritiqueConfig['fallbackPolicy'],
): CritiqueConfig['fallbackPolicy'] {
  if (raw === undefined) return fallback;
  const trimmed = raw.trim();
  if (FALLBACK_POLICIES.includes(trimmed as CritiqueConfig['fallbackPolicy'])) {
    return trimmed as CritiqueConfig['fallbackPolicy'];
  }
  throw new RangeError(
    `OD_CRITIQUE_FALLBACK_POLICY must be one of ${FALLBACK_POLICIES.join(', ')}, got "${raw}"`,
  );
}

View on GitHub (pinned to 5be4028344)

Solutions

  1. Use one of the policies printed in the error (FALLBACK_POLICIES.join(', ')) — exact casing, trimmed.
  2. Unset OD_CRITIQUE_FALLBACK_POLICY to fall back to defaultCritiqueConfig().fallbackPolicy.
  3. After a contracts upgrade, re-check the allowed list in @open-design/contracts/critique and update env accordingly.

Example fix

# before: typo'd or wrong-cased policy
OD_CRITIQUE_FALLBACK_POLICY=Strict

# after: exact value from FALLBACK_POLICIES
OD_CRITIQUE_FALLBACK_POLICY=pass   # or whichever the contracts define
Defensive patterns

Strategy: validation

Validate before calling

import { FALLBACK_POLICIES } from '@open-design/contracts/critique';
const raw = process.env.OD_CRITIQUE_FALLBACK_POLICY?.trim();
if (raw && !FALLBACK_POLICIES.includes(raw as any)) {
  throw new RangeError(`unsupported fallback policy: ${raw}`);
}

Type guard

function isFallbackPolicy(raw: string, allowed: readonly string[]): raw is CritiqueConfig['fallbackPolicy'] {
  return allowed.includes(raw);
}

Try / catch

try { loadCritiqueConfigFromEnv(); }
catch (e) {
  if (e instanceof RangeError && /FALLBACK_POLICY/.test(e.message)) {
    // fall back to defaultCritiqueConfig().fallbackPolicy
  } else throw e;
}

Prevention

When it happens

Trigger: Setting OD_CRITIQUE_FALLBACK_POLICY to a string not in FALLBACK_POLICIES — typo, wrong casing, or a value from an older version of the contracts.

Common situations: Operator typed 'strict' instead of the actual policy name; casing mismatch (e.g. 'Pass' vs 'pass'); the policy enum was renamed in a contract bump but env was not updated.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/dd0764cabcf49807. Report an issue: GitHub.