{"id":"cc413bd95ec4ac03","repo":"colinhacks/zod","slug":"invalid-template-literal-part-no-pattern-found","errorCode":null,"errorMessage":"Invalid template literal part, no pattern found: ${[...(part as any)._zod.traits].shift()}","messagePattern":"Invalid template literal part, no pattern found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/zod/src/v4/core/schemas.ts","lineNumber":4298,"sourceCode":"export type $PartsToTemplateLiteral<Parts extends $ZodTemplateLiteralPart[]> = [] extends Parts\n  ? ``\n  : Parts extends [...infer Rest, infer Last extends $ZodTemplateLiteralPart]\n    ? Rest extends $ZodTemplateLiteralPart[]\n      ? AppendToTemplateLiteral<$PartsToTemplateLiteral<Rest>, Last>\n      : never\n    : never;\n\nexport const $ZodTemplateLiteral: core.$constructor<$ZodTemplateLiteral> = /*@__PURE__*/ core.$constructor(\n  \"$ZodTemplateLiteral\",\n  (inst, def) => {\n    $ZodType.init(inst, def);\n    const regexParts: string[] = [];\n    for (const part of def.parts) {\n      if (typeof part === \"object\" && part !== null) {\n        // is Zod schema\n        if (!part._zod.pattern) {\n          // if (!source)\n          throw new Error(`Invalid template literal part, no pattern found: ${[...(part as any)._zod.traits].shift()}`);\n        }\n\n        const source = part._zod.pattern instanceof RegExp ? part._zod.pattern.source : part._zod.pattern;\n\n        if (!source) throw new Error(`Invalid template literal part: ${part._zod.traits}`);\n\n        const start = source.startsWith(\"^\") ? 1 : 0;\n        const end = source.endsWith(\"$\") ? source.length - 1 : source.length;\n        regexParts.push(source.slice(start, end));\n      } else if (part === null || util.primitiveTypes.has(typeof part)) {\n        regexParts.push(util.escapeRegex(`${part}`));\n      } else {\n        throw new Error(`Invalid template literal part: ${part}`);\n      }\n    }\n    inst._zod.pattern = new RegExp(`^${regexParts.join(\"\")}$`);\n\n    inst._zod.parse = (payload, _ctx) => {","sourceCodeStart":4280,"sourceCodeEnd":4316,"githubUrl":"https://github.com/colinhacks/zod/blob/912f0f51b0ced654d0069741e7160834dca742ee/packages/zod/src/v4/core/schemas.ts#L4280-L4316","documentation":"Thrown in the `$ZodTemplateLiteral` constructor when one of the parts is a Zod schema object but has no `_zod.pattern` (a regex describing the strings it matches). Template literals build their combined regex from each part's pattern, so any part lacking a pattern cannot contribute. The message reports the part's first trait (its type name).","triggerScenarios":"Passing a non-string-pattern schema into `z.templateLiteral(...)` — e.g. `z.object({...})`, `z.number()` (numbers have no string pattern), `z.boolean()`, `z.any()`, or a custom schema without a `_zod.pattern`. Only schemas that match strings with a regex (like `z.string().email()`, `z.literal('x')`, `z.enum([...])`) are valid template parts.","commonSituations":"Composing a template literal from mixed schema types without realizing only string-patterned schemas work; passing a nested object schema expecting it to be stringified.","solutions":["Use only string-matching schemas as dynamic parts: `z.string()`, `z.string().regex(...)`, `z.literal('x')`, `z.enum([...])`, or primitives (strings/numbers).","Replace the offending non-string schema with a `z.literal(...)` of the exact text you want interpolated.","For a numeric part, pass the JS number directly (primitives are accepted) rather than `z.number()`."],"exampleFix":"// before\nconst T = z.templateLiteral([z.literal('user:'), z.number()]); // z.number() has no pattern\n\n// after\nconst T = z.templateLiteral([z.literal('user:'), z.string().regex(/^\\d+$/)]);\n// or with a primitive part:\nconst T2 = z.templateLiteral(['id-', z.enum(['a','b'])]);","handlingStrategy":"type-guard","validationCode":"function hasStringPattern(s) {\n  return typeof s === 'object' && s !== null && !!s._zod && !!s._zod.pattern;\n}\nparts.forEach((p) => {\n  if (typeof p === 'object' && p !== null && p._zod && !hasStringPattern(p)) {\n    throw new Error('template part has no string pattern');\n  }\n});","typeGuard":"function isStringPatternSchema(s): boolean {\n  return !!s && typeof s === 'object' && !!s._zod && !!s._zod.pattern;\n}","tryCatchPattern":"try {\n  const T = z.templateLiteral(parts);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Invalid template literal part, no pattern')) {\n    // replace the non-string-pattern schema with z.literal(...) or a primitive\n  }\n  throw e;\n}","preventionTips":["Only use string-matching schemas (z.string(), z.literal, z.enum) or primitives in template literals.","For numeric content, pass the primitive number or a z.string().regex(...) instead of z.number().","Unit-test template literal construction to catch bad parts early."],"tags":["template-literal","schema-definition","regex"],"analyzedSha":"912f0f51b0ced654d0069741e7160834dca742ee","analyzedAt":"2026-08-03T17:41:55.908Z","schemaVersion":2}