mastra-ai/mastra · error
Cannot flatten intersections with overlapping keys
Error message
Cannot flatten intersections with overlapping keys
What it means
defaultZodIntersectionHandler flattens z.intersection of two ZodObjects into a single object with a merged shape when all processed members are objects. Because a true intersection can allow conflicting field types, this library refuses to merge when the same key appears in both sides, throwing instead of silently picking one type.
Solutions
- Rename the overlapping key on one side so the shapes are disjoint.
- Use z.object({ ...a.shape, ...b.shape }) manually with an explicit resolution for the shared key (e.g. omit it from one side via .omit()).
- Replace z.intersection with a single schema containing all required fields.
- Use z.union of the two objects if the value is really one shape OR the other, not both.
Example fix
// before
const schema = z.intersection(z.object({ id: z.string() }), z.object({ id: z.number() }));
// after
const schema = z.object({ id: z.string() }).extend({ score: z.number() }); Defensive patterns
Strategy: validation
Validate before calling
function assertDisjointShapes(a: z.ZodObject<any>, b: z.ZodObject<any>) {
const overlap = Object.keys(a.shape).filter(k => k in b.shape);
if (overlap.length) throw new TypeError(`Intersection keys overlap: ${overlap.join(', ')}`);
} Try / catch
try {
processed = compat.process(schema);
} catch (e) {
if ((e as Error).message.includes('overlapping keys')) {
throw new Error('Restructure: use object merge with explicit key resolution instead of z.intersection', { cause: e });
}
throw e;
} Prevention
- Prefer z.object({ ...a.shape, ...b.shape }) merges with explicit conflict handling.
- Name base/mixin keys distinctly to avoid collisions.
- Assert shape disjointness when composing schemas in tests.
When it happens
Trigger: Calling the Zod v4 schema compatibility layer with `z.intersection(z.object({ id: z.string() }), z.object({ id: z.number(), ... }))` or any two object schemas sharing at least one key.
Common situations: Combining base schemas with extension schemas (e.g. base + mixins) that both define `id`, `metadata`, or timestamps; spreading a common schema into domain schemas and then intersecting them; migrations from deepPartial/merge patterns.
Related errors
- does not support zod type
- Union must have at least 2 options
- AGENT_REQUEST_CONTEXT_VALIDATION_FAILED
- error.message (schema validation error, cause: field/errors)
- error.message (workflow schema validation error)
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/8a5a9bdd6672a2f4.
Report an issue: GitHub.
Appendix: source
Thrown at packages/schema-compat/src/schema-compatibility-v4.ts:730
}
return [value];
}
/**
* Default handler for Zod intersection types.
* Flattens the intersection tree and merges object shapes into a single z.object().
* Falls back to z.any() for non-object intersections.
*/
public defaultZodIntersectionHandler(value: ZodIntersection<any, any>): ZodType {
const leaves = this.collectIntersectionLeaves(value);
const processed = leaves.map(leaf => this.processZodType(leaf));
if (processed.every(p => p instanceof ZodObject)) {
const mergedShape: Record<string, ZodType> = {};
for (const obj of processed as ZodObject<any, any>[]) {
for (const [key, field] of Object.entries(obj.shape)) {
if (key in mergedShape) {
throw new Error('Cannot flatten intersections with overlapping keys');
}
mergedShape[key] = field as ZodType;
}
}
let result: ZodType = z.object(mergedShape);
if (value.description) {
result = result.describe(value.description);
}
return result;
}
return z.any().describe(value.description || 'intersection type');
}
/**
* Processes a Zod object schema and converts it to an AI SDK Schema.
*
* @param zodSchema - The Zod object schema to processView on GitHub (pinned to 75dd419e61)