colinhacks/zod · error · Error

Not a ZodError: ${value}

Error message

Not a ZodError: ${value}

What it means

Thrown by the static guard ZodError.assert(value), which uses `value instanceof ZodError` and throws a plain Error if the assertion fails. It exists to narrow an unknown value to a ZodError before calling ZodError-specific methods like .format() or .flatten(). It is a developer-assertion error, not a validation failure from parsing.

Source

Thrown at packages/zod/src/v3/ZodError.ts:273

            curr = curr[el];
            i++;
          }
        }
      }
    };

    processError(this);
    return fieldErrors;
  }

  static create = (issues: ZodIssue[]) => {
    const error = new ZodError(issues);
    return error;
  };

  static assert(value: unknown): asserts value is ZodError {
    if (!(value instanceof ZodError)) {
      throw new Error(`Not a ZodError: ${value}`);
    }
  }

  override toString() {
    return this.message;
  }
  override get message() {
    return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
  }

  get isEmpty(): boolean {
    return this.issues.length === 0;
  }

  addIssue = (sub: ZodIssue) => {
    this.issues = [...this.issues, sub];
  };

View on GitHub (pinned to 912f0f51b0)

Solutions

  1. Type-narrow with `error instanceof ZodError` (or `import { ZodError }`) before formatting, instead of relying on assert().
  2. If you need the assert, only call it inside a catch block where you truly expect a ZodError, and rethrow anything else.
  3. Check the value's `.name` / `.issues` array if you cannot import ZodError in that module.

Example fix

// before
try { schema.parse(data); }
catch (e) { ZodError.assert(e); return e.flatten(); }

// after
import { ZodError } from "zod";
try { schema.parse(data); }
catch (e) {
  if (e instanceof ZodError) return e.flatten();
  throw e;
}
Defensive patterns

Strategy: type-guard

Type guard

import { ZodError } from "zod";
function isZodError(e: unknown): e is ZodError {
  return e instanceof ZodError;
}

Try / catch

try { schema.parse(data); }
catch (e) {
  if (e instanceof ZodError) { /* format e */ }
  else throw e;
}

Prevention

When it happens

Trigger: Calling ZodError.assert(x) on a value that is not a ZodError instance, e.g. an Error, a string, or undefined. Common when forwarding a caught value to formatting helpers or when crossing an API boundary that promises a ZodError but delivers something else.

Common situations: Error-handling middleware that wraps parse failures; test helpers that assume every thrown value from zod is a ZodError; code that catches `unknown` after a `.parse()` and forgets the surrounding code can also throw non-ZodErrors (e.g. config errors, thrown plain Errors).


AI-assisted analysis of colinhacks/zod@912f0f51b0 (2026-08-03). Data as JSON: /data/errors/0aa0664eed08f585.json. Report an issue: GitHub.