{"record":{"id":"bea283eb419ad0fa","repo":"can1357/oh-my-pi","slug":"type-withjsonschema-cannot-wrap-schemas-with-defau","errorCode":null,"errorMessage":"type.withJsonSchema cannot wrap schemas with defaults or output-changing morphs","messagePattern":"type\\.withJsonSchema cannot wrap schemas with defaults or output-changing morphs","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/type.ts","lineNumber":3697,"sourceCode":"\t/**\n\t * Return a validation-only schema that emits `json` verbatim — even when\n\t * embedded in an object, array, or union.\n\t *\n\t * A `.toJsonSchema()` method override cannot survive nesting: a parent schema\n\t * emits each child's IR directly and never calls the child's method, so the\n\t * override silently disappears from the wire schema. This stores the override\n\t * on the IR instead.\n\t *\n\t * # Errors\n\t *\n\t * Throws when `schema` has a default or output-changing morph/pipe. A refine\n\t * can preserve validation and the input value, but silently discarding a\n\t * transformed output would violate the returned {@link Type}.\n\t */\n\texport function withJsonSchema<t, i = t>(schema: Type<t, i>, json: Record<string, unknown>): Type<t, i> {\n\t\tconst internal = schema as unknown as InternalType;\n\t\tif (internal.hasDefault || hasMorph(internal.ir) || internal[kSteps].some(step => step.kind === \"pipe\")) {\n\t\t\tthrow new OmpTypeError(\"type.withJsonSchema cannot wrap schemas with defaults or output-changing morphs\");\n\t\t}\n\t\treturn makeType<t, i>(\n\t\t\t{\n\t\t\t\tk: \"refine\",\n\t\t\t\tbase: { k: \"unknown\" },\n\t\t\t\tpred: value => {\n\t\t\t\t\tconst result = schema(value);\n\t\t\t\t\treturn result instanceof OmpErrors ? result : true;\n\t\t\t\t},\n\t\t\t\texpected: schema.expression,\n\t\t\t\tjson: { ...json },\n\t\t\t},\n\t\t\t[],\n\t\t\t{},\n\t\t);\n\t}\n}\n","sourceCodeStart":3679,"sourceCodeEnd":3715,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/type.ts#L3679-L3715","documentation":"`type.withJsonSchema(schema, json)` attaches JSON Schema metadata to a type, but it cannot faithfully represent types that carry input defaults or output-changing morphs/pipes: those change the value between input and output, and attaching a static JSON Schema would misrepresent them. Such schemas are rejected at wrap time.","triggerScenarios":"Calling `type.withJsonSchema(schema, {...})` where the schema was built with `.default(...)`, contains a morph (`.pipe(...)`, `.narrow` returning transformed values), or includes a piped step in its compiled steps.","commonSituations":"Retrofitting JSON Schema export onto an existing schema collection where some schemas have defaults added by later edits; piping in a transformation before trying to export the schema for docs/OpenAPI generation.","solutions":["Remove `.default(...)` from the schema, or attach the JSON Schema before adding the default.","Split morphs out: attach the JSON Schema to the pure validation base type, and apply the morph outside the wrapped type.","Replace pipes with plain refinements (predicates that do not transform) if the output equals the input.","Write the JSON Schema by hand for morphing types instead of using withJsonSchema."],"exampleFix":"// before\ntype.withJsonSchema(type(\"string\").pipe(s => s.trim()), {})\n// after\ntype.withJsonSchema(type(\"string\"), {}).pipe(s => s.trim())","handlingStrategy":"try-catch","validationCode":"const canAttachJsonSchema = (schema: unknown) => { const t = schema as InternalType; return !t.hasDefault && !t.expression?.includes('=>'); };","typeGuard":null,"tryCatchPattern":"try { return type.withJsonSchema(schema, json); } catch (e) { if (e instanceof OmpTypeError) return stripMorphsThenWrap(schema, json); throw e; }","preventionTips":["Attach JSON Schema metadata to pure validation types before adding defaults or pipes","Keep morphs outside schemas destined for JSON Schema export","Maintain a separate 'export shape' schema for docs generation when the runtime schema morphs"],"tags":["json-schema","morph","defaults","schema"],"backgroundTag":"json-schema-unsupported-type","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}