{"record":{"id":"c7ef0e3991a85c8e","repo":"can1357/oh-my-pi","slug":"parseerror-invalid-intersection-of-default-values","errorCode":null,"errorMessage":"ParseError: Invalid intersection of default values ${String(ap.def)} & ${String(bp.def)}","messagePattern":"ParseError: Invalid intersection of default values (.+?) & (.+?)","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/type.ts","lineNumber":2054,"sourceCode":"\t\t}\n\t\tif (members.length === 0) throw new OmpTypeError(\"intersection has no satisfiable branches\");\n\t\treturn members.length === 1 ? members[0] : { k: \"union\", members };\n\t}\n\tif (a.k === \"lit\") {\n\t\tif (walk(b, a.v) instanceof OmpErrors) throw new OmpTypeError(\"literal is excluded by the intersection\");\n\t\treturn a;\n\t}\n\tif (b.k === \"lit\") return intersect(b, a);\n\tif (a.k === \"object\" && b.k === \"object\") {\n\t\tconst props = [...a.props];\n\t\tfor (const bp of b.props) {\n\t\t\tconst index = props.findIndex(prop => prop.key === bp.key);\n\t\t\tif (index < 0) props.push(bp);\n\t\t\telse {\n\t\t\t\tconst ap = props[index];\n\t\t\t\tconst required = (!ap.opt && !ap.hasDefault) || (!bp.opt && !bp.hasDefault);\n\t\t\t\tif (ap.hasDefault && bp.hasDefault && !Object.is(ap.def, bp.def)) {\n\t\t\t\t\tthrow new OmpTypeError(\n\t\t\t\t\t\t`ParseError: Invalid intersection of default values ${String(ap.def)} & ${String(bp.def)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst defaulted = required ? undefined : ap.hasDefault ? ap : bp.hasDefault ? bp : undefined;\n\t\t\t\tprops[index] = {\n\t\t\t\t\tkey: ap.key,\n\t\t\t\t\topt: ap.opt && bp.opt,\n\t\t\t\t\tval: intersect(ap.val, bp.val),\n\t\t\t\t\t...(defaulted\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tdef: defaulted.def,\n\t\t\t\t\t\t\t\tdefFactory: defaulted.defFactory,\n\t\t\t\t\t\t\t\thasDefault: true,\n\t\t\t\t\t\t\t\tdefValidated: defaulted.defValidated,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t};\n\t\t\t}","sourceCodeStart":2036,"sourceCodeEnd":2072,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/type.ts#L2036-L2072","documentation":"When intersecting two object types that share a property key where BOTH sides declare a default value and those defaults differ (by Object.is), the intersection cannot pick a single default, so the library throws. Intersections must yield one deterministic default for each property.","triggerScenarios":"intersect(object({retries: opt(number).default(3)}), object({retries: opt(number).default(5)})) — same key, two different .default(...) values; typically from merging two schema definitions of the same object.","commonSituations":"Base schema and override schema both specifying .default() for the same option with different values; a vendor schema and a local refinement both defaulting a field; copy-pasted schema fragments drifting apart.","solutions":["Make the defaults identical on both sides","Remove .default() from one of the two operands so only one side supplies a default","Merge the schemas at the source (one canonical definition) instead of intersecting","Catch OmpTypeError and report which key/defaults conflict"],"exampleFix":"// before\nintersect(object({retries: number().opt().default(3)}), object({retries: number().opt().default(5)}));\n// after\nintersect(object({retries: number().opt().default(3)}), object({retries: number().opt()}));","handlingStrategy":"validation","validationCode":"function hasConflictingDefaults(a, b, key) {\n  const pa = a.props?.find(p => p.key === key);\n  const pb = b.props?.find(p => p.key === key);\n  return pa?.hasDefault && pb?.hasDefault && !Object.is(pa.def, pb.def);\n}","typeGuard":"const isOmpTypeError = (e: unknown): e is OmpTypeError => e instanceof OmpTypeError;","tryCatchPattern":"try {\n  const merged = intersect(baseSchema, overrideSchema);\n} catch (err) {\n  if (err instanceof OmpTypeError && err.message.startsWith('ParseError: Invalid intersection of default values')) {\n    logger.warn('conflicting defaults in schema intersection', { message: err.message });\n  } else throw err;\n}","preventionTips":["Give each option exactly one .default() — declare defaults only in the base schema","Centralize schema definitions; do not copy-paste object fragments that both add defaults","When overriding, use a plain optional property (opt()) instead of re-declaring a default","Add a schema-build smoke test that intersects all shipped schema pairs"],"tags":["types","schema","defaults","intersection","omptype"],"backgroundTag":"conflicting-schema-defaults","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}