{"record":{"id":"8f7df45f64204178","repo":"mastra-ai/mastra","slug":"union-must-have-at-least-2-options","errorCode":null,"errorMessage":"Union must have at least 2 options","messagePattern":"Union must have at least 2 options","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/schema-compat/src/schema-compatibility-v3.ts","lineNumber":438,"sourceCode":"    }\n\n    const description = this.mergeParameterDescription(value.description, constraints);\n    if (description) {\n      result = result.describe(description);\n    }\n    return result;\n  }\n\n  /**\n   * Default handler for Zod union types. Processes all union options.\n   *\n   * @param value - The Zod union to process\n   * @returns The processed Zod union\n   * @throws Error if union has fewer than 2 options\n   */\n  public defaultZodUnionHandler(value: ZodUnion<[ZodTypeAny, ...ZodTypeAny[]]>): ZodTypeAny {\n    const processedOptions = value._def.options.map((option: ZodTypeAny) => this.processZodType(option));\n    if (processedOptions.length < 2) throw new Error('Union must have at least 2 options');\n    let result = z.union(processedOptions as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);\n    if (value.description) {\n      result = result.describe(value.description);\n    }\n    return result;\n  }\n\n  /**\n   * Default handler for Zod string types. Processes string validation constraints.\n   *\n   * @param value - The Zod string to process\n   * @param handleChecks - String constraints to convert to descriptions vs keep as validation\n   * @returns The processed Zod string\n   */\n  public defaultZodStringHandler(\n    value: ZodString,\n    handleChecks: readonly StringCheckType[] = ALL_STRING_CHECKS,\n  ): ZodString {","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/schema-compat/src/schema-compatibility-v3.ts#L420-L456","documentation":"defaultZodUnionHandler in schema-compatibility-v3 rebuilds Zod unions after processing each option, then asserts at least 2 options exist since z.union() requires a tuple of 2+. This guard fires when the processed union somehow ended up with fewer than 2 options.","triggerScenarios":"Passing a union with fewer than two options into the compatibility layer — typically a TypeScript edge case where a union type collapsed to a single member, or building a union dynamically at runtime from an array that yielded one option.","commonSituations":"Runtime-constructed schemas where `options.length === 1` (should have been the bare type, not a union); refactors that removed a union member; wrapped/generated schemas mis-typed as ZodUnion.","solutions":["Ensure the union has at least two distinct options, e.g. z.union([z.string(), z.number()]).","If only one option remains, use that option directly instead of wrapping it in z.union().","If options are built at runtime, filter/branch so single-option arrays become the plain type.","Verify you are not mis-tagging a non-union type as a union before the handler."],"exampleFix":"// before\nconst schema = z.union([z.string()]);\n// after\nconst schema = z.string(); // or add a second option to the union","handlingStrategy":"validation","validationCode":"function toUnionOrSingle(types: z.ZodTypeAny[]): z.ZodTypeAny {\n  if (types.length === 0) throw new TypeError('Need at least one type');\n  return types.length === 1 ? types[0] : z.union(types as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]);\n}","typeGuard":"function isValidUnion(u: z.ZodUnion<[z.ZodTypeAny, ...z.ZodTypeAny[]]>): boolean {\n  return u._def.options.length >= 2;\n}","tryCatchPattern":"try {\n  processed = compat.process(schema);\n} catch (e) {\n  if (e.message === 'Union must have at least 2 options') {\n    throw new Error('Schema builds a union with <2 options; unwrap single-option unions', { cause: e });\n  }\n  throw e;\n}","preventionTips":["Never construct z.union from arrays without checking length >= 2.","Use the bare type for single-branch cases; use optional/nullable for optionality.","Assert union arity in generated-schema tests."],"tags":["zod","union","schema"],"backgroundTag":"union-too-few-options","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}