colinhacks/zod · error · Error

Unsupported type

Error message

Unsupported type: ${type}

What it means

Thrown by the default branch of the type switch in convertBaseSchema (packages/zod/src/v4/classic/from-json-schema.ts:529) when schema.type is a string the converter does not handle. The converter supports exactly: string, number, integer, boolean, null, object, array (type arrays are expanded into a union before the switch, so only single-string types reach it). Any other value — a typo, a custom vocabulary type, or a non-standard draft keyword — falls through to this guard.

Solutions

  1. Inspect the type value reported in the message and correct it to one of: string, number, integer, boolean, null, object, array.
  2. If the type is a typo (e.g. 'strign'), fix the source document.
  3. If the type represents a concept Zod has no equivalent for, replace the subschema with an inline schema Zod can express (e.g. use z.any() or a refined z.string() for custom types).
  4. Pre-scan the document for type values outside the supported set and log them before conversion.

Example fix

// before
const schema = { type: 'strign', minLength: 1 };
fromJSONSchema(schema); // throws: Unsupported type: strign

// after
const schema = { type: 'string', minLength: 1 };
fromJSONSchema(schema);
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'null', 'object', 'array']);

function assertSupportedTypes(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 (typeof o.type === 'string' && !SUPPORTED_TYPES.has(o.type)) {
      throw new Error(`Unsupported JSON Schema type: '${o.type}'`);
    }
    for (const v of Object.values(o)) visit(v);
  };
  visit(root);
}

Type guard

function isSupportedType(type: unknown): type is 'string' | 'number' | 'integer' | 'boolean' | 'null' | 'object' | 'array' {
  return typeof type === 'string' && ['string', 'number', 'integer', 'boolean', 'null', 'object', 'array'].includes(type);
}

Try / catch

null

Prevention

When it happens

Trigger: Calling fromJSONSchema on a schema whose `type` is something other than the supported set, e.g. `{ type: 'symbol' }`, `{ type: 'bigint' }`, `{ type: 'any' }`, or a typo like `{ type: 'strign' }`. Also triggered by OpenAPI-specific or custom-vocabulary type values that aren't part of the core JSON Schema type set.

Common situations: Hand-written schemas with typos in the type field; schemas using non-standard 'type' values from extended vocabularies; documents generated from TypeScript types that map unknown TS types (symbol, function, Date-as-type) onto the type field; OpenAPI extensions inventing type names.

Related errors


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

Appendix: source

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

        // Apply constraints
        if (typeof schema.minItems === "number") {
          arraySchema = arraySchema.min(schema.minItems);
        }
        if (typeof schema.maxItems === "number") {
          arraySchema = arraySchema.max(schema.maxItems);
        }

        zodSchema = arraySchema;
      } else {
        // No items specified - array of any
        zodSchema = z.array(z.any());
      }
      break;
    }

    default:
      throw new Error(`Unsupported type: ${type}`);
  }

  return zodSchema;
}

function convertSchema(schema: JSONSchema.JSONSchema | boolean, ctx: ConversionContext): ZodType {
  if (typeof schema === "boolean") {
    return schema ? z.any() : z.never();
  }

  // Convert base schema first (ignoring composition keywords)
  let baseSchema = convertBaseSchema(schema, ctx);
  const hasExplicitType = schema.type || schema.enum !== undefined || schema.const !== undefined;

  // Process composition keywords LAST (they can appear together)
  // Handle anyOf - wrap base schema with union
  if (schema.anyOf && Array.isArray(schema.anyOf)) {
    const options = schema.anyOf.map((s) => convertSchema(s, ctx));

View on GitHub (pinned to 2d90846af9)