{"record":{"id":"df680af9a392e8f4","repo":"can1357/oh-my-pi","slug":"parseerror-a-mutable-default-value-must-be-specif","errorCode":null,"errorMessage":"ParseError: A mutable default value must be specified as a factory","messagePattern":"ParseError: A mutable default value must be specified as a factory","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/type.ts","lineNumber":628,"sourceCode":"\tconst error = errors[0];\n\tlet heading = label;\n\tfor (let index = 0; index < error.path.length; index++) {\n\t\tconst segment = error.path[index];\n\t\tif (typeof segment === \"number\") {\n\t\t\tif (label === \"Default\" && index === 0) heading = \"Default value\";\n\t\t\theading += ` at [${segment}]`;\n\t\t} else if (label === \"Default\" && index === 0) {\n\t\t\theading += ` ${String(segment)}`;\n\t\t} else {\n\t\t\theading += `.${String(segment)}`;\n\t\t}\n\t}\n\tthrow new OmpTypeError(`ParseError: ${heading} ${error.problem}`);\n}\n\nfunction rejectMutableStaticDefault(value: unknown): void {\n\tif (value !== null && typeof value === \"object\" && !(value instanceof Date)) {\n\t\tthrow new OmpTypeError(\"ParseError: A mutable default value must be specified as a factory\");\n\t}\n}\n\nfunction normalizeDefaults(ir: IR, seen = new WeakSet<object>()): void {\n\tif (seen.has(ir)) return;\n\tseen.add(ir);\n\tswitch (ir.k) {\n\t\tcase \"object\":\n\t\t\tfor (const prop of ir.props) {\n\t\t\t\tnormalizeDefaults(prop.val, seen);\n\t\t\t\tif (!prop.hasDefault || prop.defValidated) continue;\n\t\t\t\tlet candidate: unknown;\n\t\t\t\tlet factory = false;\n\t\t\t\tif (prop.defFactory && typeof prop.def === \"function\") {\n\t\t\t\t\tcandidate = prop.def();\n\t\t\t\t\tfactory = true;\n\t\t\t\t} else {\n\t\t\t\t\trejectMutableStaticDefault(prop.def);","sourceCodeStart":610,"sourceCodeEnd":646,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/type.ts#L610-L646","documentation":"omptype forbids static (non-factory) default values that are mutable objects, because a single shared object instance would be reused across every parse and mutations would leak between results. `rejectMutableStaticDefault` throws this ParseError when `.default(obj)` or an object-literal default receives a non-null object that is not a Date. Null and Date are exempt.","triggerScenarios":"`type({...}).default({ a: 1 })`, `type('string[]').default([])`, or an object property declared with `[]`/`{}` as a static default via `normalizeDefaults`.","commonSituations":"Defaults for arrays/objects copied from other schema libraries (like plain JSON defaults); users unaware that static object defaults create shared-state bugs.","solutions":["Wrap the default in a factory: `.default(() => [])`.","Use `.default(() => ({ a: 1 }))` for object defaults.","If an intentionally shared immutable default is needed, freeze it — but prefer factories."],"exampleFix":"// before\nconst T = type({ tags: 'string[]' }).default({ tags: [] }); // throws\n\n// after\nconst T = type({ tags: 'string[]' }).default(() => ({ tags: [] }));","handlingStrategy":"validation","validationCode":"function safeDefault(T, value) {\n  if (value !== null && typeof value === 'object' && !(value instanceof Date)) {\n    return T.default(() => value);\n  }\n  return T.default(value);\n}","typeGuard":"function isMutableStaticDefault(v) {\n  return v !== null && typeof v === 'object' && !(v instanceof Date);\n}","tryCatchPattern":"try {\n  const T = type({ tags: 'string[]' }).default([]);\n} catch (e) {\n  if (e instanceof OmpTypeError && e.message.includes('must be specified as a factory')) {\n    // retry with factory or fix call site\n  } else throw e;\n}","preventionTips":["Habit: always use `.default(() => ...)` for arrays and objects, even single-use.","Never inline `[]` or `{}` as static defaults.","Search codebases for `.default({` and `.default([` during reviews."],"tags":["parse-error","default-value","mutability"],"backgroundTag":"mutable-default-requires-factory","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}