colinhacks/zod · error · Error

Invalid template literal part: ${part._zod.traits}

Error message

Invalid template literal part: ${part._zod.traits}

What it means

Thrown in `$ZodTemplateLiteral` when a schema part has a `_zod.pattern` key but its resolved source string is empty/falsy. This is an edge case: the schema reported a pattern object/RegExp but it had no usable source text, so the combined regex cannot be built.

Source

Thrown at packages/zod/src/v4/core/schemas.ts:4303

      : never
    : never;

export const $ZodTemplateLiteral: core.$constructor<$ZodTemplateLiteral> = /*@__PURE__*/ core.$constructor(
  "$ZodTemplateLiteral",
  (inst, def) => {
    $ZodType.init(inst, def);
    const regexParts: string[] = [];
    for (const part of def.parts) {
      if (typeof part === "object" && part !== null) {
        // is Zod schema
        if (!part._zod.pattern) {
          // if (!source)
          throw new Error(`Invalid template literal part, no pattern found: ${[...(part as any)._zod.traits].shift()}`);
        }

        const source = part._zod.pattern instanceof RegExp ? part._zod.pattern.source : part._zod.pattern;

        if (!source) throw new Error(`Invalid template literal part: ${part._zod.traits}`);

        const start = source.startsWith("^") ? 1 : 0;
        const end = source.endsWith("$") ? source.length - 1 : source.length;
        regexParts.push(source.slice(start, end));
      } else if (part === null || util.primitiveTypes.has(typeof part)) {
        regexParts.push(util.escapeRegex(`${part}`));
      } else {
        throw new Error(`Invalid template literal part: ${part}`);
      }
    }
    inst._zod.pattern = new RegExp(`^${regexParts.join("")}$`);

    inst._zod.parse = (payload, _ctx) => {
      if (typeof payload.value !== "string") {
        payload.issues.push({
          input: payload.value,
          inst,
          expected: "string",

View on GitHub (pinned to 912f0f51b0)

Solutions

  1. Inspect the offending schema's `_zod.pattern` and ensure it resolves to a non-empty RegExp source.
  2. Replace the problematic part with a `z.string().regex(<non-empty>)` or `z.literal(...)` whose pattern is well-defined.
  3. If using a custom schema, ensure its `pattern` property is a non-empty RegExp before passing it to a template literal.

Example fix

// before
const part = z.string().regex(//); // empty pattern
const T = z.templateLiteral([z.literal('x'), part]);

// after
const part = z.string().regex(/^[0-9]+/);
const T = z.templateLiteral([z.literal('x'), part]);
Defensive patterns

Strategy: validation

Validate before calling

function hasNonEmptyPattern(s) {
  const p = s?._zod?.pattern;
  if (!p) return false;
  const src = p instanceof RegExp ? p.source : p;
  return typeof src === 'string' && src.length > 0;
}

Type guard

function hasNonEmptyPattern(s): boolean {
  const p = s?._zod?.pattern;
  if (!p) return false;
  const src = p instanceof RegExp ? p.source : p;
  return typeof src === 'string' && src.length > 0;
}

Try / catch

try {
  const T = z.templateLiteral(parts);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Invalid template literal part:')) {
    // inspect each part's _zod.pattern source and replace empty ones
  }
  throw e;
}

Prevention

When it happens

Trigger: A custom or transformed schema whose `pattern` is set to an empty string or a RegExp with empty source; a schema whose pattern getter returns undefined under certain config. Rare in normal usage — usually from custom schemas or unusual transforms.

Common situations: Custom Zod extensions that set `_zod.pattern` incorrectly; chaining transforms that erase the pattern; edge cases in third-party plugins.

Related errors


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