colinhacks/zod · error · Error

Invalid template literal part

Error message

Invalid template literal part: ${part}

What it means

Thrown by $ZodTemplateLiteral when a part is neither a Zod-schema object (no _zod.pattern branch) nor a primitive/null that the constructor knows how to inline. This is the catch-all for unrecognized part types — functions, class constructors, plain objects without _zod, Symbols that aren't in util.primitiveTypes, etc. The message prints the part itself.

Solutions

  1. Pass only Zod schema instances or primitive values (string/number/boolean/null/undefined/bigint) as template parts.
  2. If you wrote z.string instead of z.string(), add the parentheses.
  3. Convert plain config objects to schemas with z.object() before embedding.
  4. For dynamic fragments, stringify the value first and embed it as a plain string part.

Example fix

// before
const T = z.template`id-${z.string}`; // forgot to call
// after
const T = z.template`id-${z.string()}`;
Defensive patterns

Strategy: type-guard

Validate before calling

function isTemplatePart(part: unknown): boolean {
  if (part === null || part === undefined) return true;
  const t = typeof part;
  return t === "string" || t === "number" || t === "boolean" || t === "bigint" ||
         (t === "object" && !!(part as any)?._zod?.pattern);
}

Type guard

function isTemplatePart(part: unknown): boolean {
  if (part === null || part === undefined) return true;
  const t = typeof part;
  return t === "string" || t === "number" || t === "boolean" || t === "bigint" ||
         (t === "object" && !!(part as any)?._zod?.pattern);
}

Prevention

When it happens

Trigger: Calling z.template`${() => "x"}`, z.template`${SomeClass}`, z.template`${{ foo: 1 }}`, z.template`${Symbol("x")}`, or passing any non-schema, non-primitive value as a template part. Often the result of forgetting to call a schema factory (z.string vs z.string()) or passing a schema definition object instead of an instance.

Common situations: Forgetting parentheses on a schema factory (passing the function reference instead of its result); passing a config object where a schema is expected; passing a class constructor; Symbol parts; copy-paste from code that used a different templating library.

Related errors


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

Appendix: source

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

    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",
          code: "invalid_type",
        });
        return payload;
      }

      inst._zod.pattern.lastIndex = 0;

      if (!inst._zod.pattern.test(payload.value)) {

View on GitHub (pinned to 2d90846af9)