colinhacks/zod · error · Error

unevaluatedItems is not supported

Error message

unevaluatedItems is not supported

What it means

Thrown by convertBaseSchema (packages/zod/src/v4/classic/from-json-schema.ts:157) when the source JSON Schema contains the `unevaluatedItems` keyword (a draft-2019+ feature that constrains array items not validated by items/prefixItems/contains). Zod arrays have no notion of 'unevaluated' items tied to composition evaluation, so the converter refuses the document rather than silently dropping the constraint.

Solutions

  1. Delete the `unevaluatedItems` key from the source schema before conversion (its semantics have no Zod equivalent).
  2. If the intent was strict rejection of extras, model it with z.tuple + .rest(z.never()) or z.array with a maxItems/minItems bound.
  3. Pre-process the document to strip unsupported draft-2019+ keys.
  4. Validate the source schema against the converter's supported feature list before calling fromJSONSchema.

Example fix

// before
const schema = {
  type: 'array',
  items: { type: 'string' },
  unevaluatedItems: false,
};
fromJSONSchema(schema); // throws

// after — drop the unsupported keyword
const schema = { type: 'array', items: { type: 'string' } };
fromJSONSchema(schema);
Defensive patterns

Strategy: validation

Validate before calling

function assertNoUnevaluatedItems(root: unknown) {
  const visit = (node: unknown): void => {
    if (Array.isArray(node)) return node.forEach(visit);
    if (!node || typeof node !== 'object') return;
    const o = node as Record<string, unknown>;
    if ('unevaluatedItems' in o) throw new Error('Schema uses unevaluatedItems, which Zod cannot express');
    for (const v of Object.values(o)) visit(v);
  };
  visit(root);
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Calling fromJSONSchema on a schema that includes `unevaluatedItems`, typically `{ type: 'array', items: {...}, unevaluatedItems: false }` or `unevaluatedItems: { ... }`. Any presence of the key triggers the throw regardless of its value.

Common situations: Converting draft-2019/2020-12 schemas authored with unevaluatedItems for strict array validation; schemas generated by strict validators (e.g. ajv with useDefaults/strict mode); OpenAPI 3.1 documents that adopted the 2019-09 vocabulary.

Related errors


AI-assisted analysis of colinhacks/zod@2d90846af9 (2026-08-11). Data as JSON: /api/errors/892885ff562bf460. Report an issue: GitHub.

Appendix: source

Thrown at packages/zod/src/v4/classic/from-json-schema.ts:157

      throw new Error(`Reference not found: ${ref}`);
    }
    return ctx.defs[key]!;
  }

  throw new Error(`Reference not found: ${ref}`);
}

function convertBaseSchema(schema: JSONSchema.JSONSchema, ctx: ConversionContext): ZodType {
  // Handle unsupported features
  if (schema.not !== undefined) {
    // Special case: { not: {} } represents never
    if (typeof schema.not === "object" && Object.keys(schema.not).length === 0) {
      return z.never();
    }
    throw new Error("not is not supported in Zod (except { not: {} } for never)");
  }
  if (schema.unevaluatedItems !== undefined) {
    throw new Error("unevaluatedItems is not supported");
  }
  if (schema.unevaluatedProperties !== undefined) {
    throw new Error("unevaluatedProperties is not supported");
  }
  if (schema.if !== undefined || schema.then !== undefined || schema.else !== undefined) {
    throw new Error("Conditional schemas (if/then/else) are not supported");
  }
  if (schema.dependentSchemas !== undefined || schema.dependentRequired !== undefined) {
    throw new Error("dependentSchemas and dependentRequired are not supported");
  }

  // Handle $ref
  if (schema.$ref) {
    const refPath = schema.$ref;
    if (ctx.refs.has(refPath)) {
      return ctx.refs.get(refPath)!;
    }

View on GitHub (pinned to 2d90846af9)