{"record":{"id":"36b4d03cbcf1f479","repo":"can1357/oh-my-pi","slug":"pipe-operands-must-be-functions-or-types","errorCode":null,"errorMessage":"pipe operands must be functions or Types","messagePattern":"pipe operands must be functions or Types","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/type.ts","lineNumber":1339,"sourceCode":"\t\t\tif (\n\t\t\t\t!forcePipeline &&\n\t\t\t\tschema[kSteps].length === 0 &&\n\t\t\t\t!target.hasSteps &&\n\t\t\t\t!hasMorph(schema.ir) &&\n\t\t\t\t!hasMorph(target.ir)\n\t\t\t) {\n\t\t\t\tschema = makeType(intersect(schema.ir, target.ir), [], metaOf(schema));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst out = target.opaqueOutput ? undefined : (target.stepOut ?? target.ir);\n\t\t\tschema = makeType(\n\t\t\t\tschema.ir,\n\t\t\t\t[...schema[kSteps], { kind: \"pipe\", fn: value => target.run(value), out, try: catchErrors }],\n\t\t\t\tmetaOf(schema),\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof candidate !== \"function\") throw new OmpTypeError(\"pipe operands must be functions or Types\");\n\t\tschema = makeType(\n\t\t\tschema.ir,\n\t\t\t[...schema[kSteps], { kind: \"pipe\", fn: candidate as Step[\"fn\"], try: catchErrors }],\n\t\t\tmetaOf(schema),\n\t\t);\n\t}\n\treturn inheritScope(source, schema);\n}\n\nfunction projectIO(ir: IR, io: \"in\" | \"out\"): IR {\n\tswitch (ir.k) {\n\t\tcase \"morph\":\n\t\t\treturn projectIO(io === \"in\" || ir.out === undefined ? ir.input : ir.out, io);\n\t\tcase \"sub\":\n\t\t\tif (io === \"out\" && ir.schema.opaqueOutput) return { k: \"unknown\" };\n\t\t\treturn projectIO(io === \"out\" ? (ir.schema.stepOut ?? ir.schema.ir) : ir.schema.ir, io);\n\t\tcase \"array\":\n\t\t\treturn { ...ir, el: projectIO(ir.el, io) };","sourceCodeStart":1321,"sourceCodeEnd":1357,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/type.ts#L1321-L1357","documentation":"`type.pipe(...)` accepts only functions and Types as operands. When an operand is neither a Type (handled above) nor a function, the pipeline builder throws 'pipe operands must be functions or Types' as an OmpTypeError, because there is no way to turn it into a step.","triggerScenarios":"`type('string').pipe(42)`, `.pipe(undefined)` (e.g. an optional callback not provided), passing a plain object or string where a transform was intended, or a mis-imported identifier that is undefined at runtime.","commonSituations":"Circular-import shadowing making a transform function undefined; passing a schema-like object from another library expecting auto-conversion; typos in the transform function reference.","solutions":["Pass an actual function: `type('string').pipe(s => s.trim())`.","Pass a Type created by omptype: `.pipe(otherType)`.","Check for undefined operands from import cycles or missing arguments; log the operand before piping.","If piping into another library's validator, wrap it: `.pipe(v => otherValidator.parse(v))`."],"exampleFix":"// before\ntype('string').pipe(someValidator); // plain object, throws\n\n// after\ntype('string').pipe(v => someValidator.parse(v));","handlingStrategy":"validation","validationCode":"const operands = [step1, step2];\nfor (const op of operands) {\n  if (typeof op !== 'function' && !(op instanceof OmpType)) {\n    throw new Error(`bad pipe operand: ${String(op)}`);\n  }\n}\ntype('string').pipe(...operands);","typeGuard":"function isPipeOperand(op) {\n  return typeof op === 'function' || op instanceof OmpType;\n}","tryCatchPattern":"try {\n  const T = base.pipe(...steps);\n} catch (e) {\n  if (e instanceof OmpTypeError && e.message.includes('pipe operands')) {\n    // filter steps: steps.filter(isPipeOperand) and retry\n  } else throw e;\n}","preventionTips":["Type step arrays as `(fn | Type)[]` so bad operands fail at compile time.","Beware circular imports that turn transform functions into `undefined` at call time.","Wrap third-party validators in a function before piping."],"tags":["pipe","type-error","api-misuse"],"backgroundTag":"invalid-pipe-operand","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}