JuliusBrussee/caveman · error · MiddlewareError

unknown_capability

unknown_capability

Error message

unknown_capability

What it means

MiddlewareError with code 'unknown_capability' is thrown by validateCapabilities when a transform entry in a Capabilities object fails leaf validation. The library validates every declared transform before an adapter is allowed to apply any of them, so a single malformed transform invalidates the whole capability set. Checks include token-shaped transform_id (unique), token-shaped implementation_version, an array eligible_segment_kinds, recovery of 'exact_ccr' or 'none', and deterministic === true.

Solutions

  1. Fix the offending transform entry: make transform_id and implementation_version valid tokens and ensure each transform_id is unique in the array
  2. Set recovery to exactly 'exact_ccr' or 'none'
  3. Set deterministic to the boolean true (not 1, not a string)
  4. Ensure eligible_segment_kinds is a non-null array of segment kinds
  5. Log/inspect the capabilities object before validation to find which transform fails

Example fix

// before
{ transform_id: 'compress json', recovery: 'exact', deterministic: 1 }
// after
{ transform_id: 'compress-json', implementation_version: '1.0.0', eligible_segment_kinds: ['json'], recovery: 'exact_ccr', deterministic: true }
Defensive patterns

Strategy: validation

Validate before calling

function validTransform(t) {
  return t && isToken(t.transform_id) && isToken(t.implementation_version) &&
    Array.isArray(t.eligible_segment_kinds) &&
    ['exact_ccr','none'].includes(t.recovery) && t.deterministic === true;
}
const seen = new Set();
if (!c.transforms.every(t => validTransform(t) && !seen.has(t.transform_id) && seen.add(t.transform_id)))
  throw new Error('capability transform invalid before calling validateCapabilities');

Type guard

const isCapabilities = (c) => !!c && c.schema_version === 1 && Array.isArray(c.transforms) &&
  c.transforms.every(t => typeof t?.transform_id === 'string' && typeof t?.deterministic === 'boolean' &&
    (t.recovery === 'exact_ccr' || t.recovery === 'none'));

Try / catch

try { await validateCapabilities(value); } catch (e) {
  if (e.code === 'unknown_capability') {
    const bad = value.transforms.findIndex(t => !isCapabilities({ transforms: [t] }));
    console.error(`invalid transform at index ${bad}:`, value.transforms[bad]);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling validateCapabilities with a Capabilities object whose transforms array contains: a transform_id that is not a valid token, a duplicate transform_id, an implementation_version that is not a token, eligible_segment_kinds missing or not an array, a recovery value other than 'exact_ccr'/'none', or deterministic not strictly true.

Common situations: Hand-written capability manifests with typos in recovery ('exact', 'ccr'), deterministic omitted or set to 1 instead of true, the same transform listed twice after copy-paste, kebab/underscored transform ids failing isToken, or an upgrade that renamed recovery enum values.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/5bb64bd81331da3b. Report an issue: GitHub.

Appendix: source

Thrown at packages/sdk/typescript/src/middleware/validate.ts:27

export const isToken = (s: unknown): s is string => typeof s === 'string' && /^[a-zA-Z0-9._:/-]{1,256}$/.test(s);
const integer = (n: unknown): n is number => Number.isSafeInteger(n) && (n as number) >= 0;
export function scopeKey(scope: Scope): string {
  if (![scope.namespace, scope.session_id, scope.branch_id, scope.cache_epoch].every(isToken)) throw new MiddlewareError('invalid_scope');
  return JSON.stringify([scope.namespace, scope.session_id, scope.branch_id, scope.cache_epoch]);
}
export class MiddlewareError extends Error {
  constructor(readonly code: string) { super(`Caveman middleware: ${code}`); this.name = 'MiddlewareError'; }
}
export function validateCapabilities(value: unknown): Capabilities {
  const c = value as Capabilities;
  if (!c || c.schema_version !== 1 || !isToken(c.policy_revision) || typeof c.runtime_build !== 'string' ||
    !['record', 'compress'].includes(c.mode) || !Array.isArray(c.transforms) || c.transforms.length > 128 ||
    !c.limits || !Object.values(c.limits).every(n => integer(n) && n > 0) ||
    !integer(c.retention_seconds) || typeof c.recovery !== 'boolean' || typeof c.persistent !== 'boolean') throw new MiddlewareError('unsupported_version');
  const ids = new Set<string>();
  for (const t of c.transforms) {
    if (!isToken(t.transform_id) || ids.has(t.transform_id) || !isToken(t.implementation_version) || !Array.isArray(t.eligible_segment_kinds) ||
      !['exact_ccr', 'none'].includes(t.recovery) || t.deterministic !== true) throw new MiddlewareError('unknown_capability');
    ids.add(t.transform_id);
  }
  return c;
}

/** Validate every leaf before an adapter is allowed to apply any of them. */
export async function validatePlan(value: unknown, request: OptimizeRequest, inputDigest: string, caps: Capabilities): Promise<Plan> {
  const p = value as Plan;
  const invalid = () => { throw new MiddlewareError('invalid_plan'); };
  if (!p || p.schema_version !== 1 || p.request_id !== request.request_id || p.input_digest !== inputDigest ||
    p.policy_revision !== request.policy.revision || !isHash(p.replacement_set_id) || !['optimized','bypassed','record'].includes(p.status) ||
    !isToken(p.reason) || !Array.isArray(p.replacements) || !Array.isArray(p.skipped) || !p.measurement || !p.stability || !p.recovery) invalid();
  const m = p.measurement;
  if (m.basis !== 'inferred' || m.scope !== 'segment' || m.verified_saved_usd !== 0 || typeof m.tokenizer !== 'string' ||
    ![m.tokens_before,m.tokens_after,m.unique_tokens_reduced,m.recovery_overhead_tokens].every(integer) || m.tokens_after > m.tokens_before ||
    p.stability.provider_bytes !== 'unobserved' || p.stability.provider_cache_hits !== 'unobserved' || !['persistent_choices','unavailable'].includes(p.stability.native) ||
    typeof p.recovery.available !== 'boolean' || typeof p.recovery.persistent !== 'boolean' || !integer(p.recovery.expires_at)) invalid();
  const seen = new Set<string>();

View on GitHub (pinned to 3ee70a1026)