{"record":{"id":"91c5f9450c7efc9b","repo":"jquense/yup","slug":"method-function-must-be-provided","errorCode":null,"errorMessage":"Method function must be provided","messagePattern":"Method function must be provided","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/index.ts","lineNumber":61,"sourceCode":"\nfunction addMethod<T extends ISchema<any>>(\n  schemaType: (...arg: any[]) => T,\n  name: string,\n  fn: (this: T, ...args: any[]) => T,\n): void;\nfunction addMethod<T extends abstract new (...args: any) => ISchema<any>>(\n  schemaType: T,\n  name: string,\n  fn: (this: InstanceType<T>, ...args: any[]) => InstanceType<T>,\n): void;\nfunction addMethod(schemaType: any, name: string, fn: any) {\n  if (!schemaType || !isSchema(schemaType.prototype))\n    throw new TypeError('You must provide a yup schema constructor function');\n\n  if (typeof name !== 'string')\n    throw new TypeError('A Method name must be provided');\n  if (typeof fn !== 'function')\n    throw new TypeError('Method function must be provided');\n\n  schemaType.prototype[name] = fn;\n}\n\nexport type AnyObjectSchema = ObjectSchema<any, any, any, any>;\n\nexport type CastOptions = Omit<BaseCastOptions, 'path' | 'resolved'>;\n\nexport type {\n  AnyMessageParams,\n  AnyObject,\n  InferType,\n  InferType as Asserts,\n  ISchema,\n  Message,\n  MessageParams,\n  AnySchema,\n  MixedOptions,","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/jquense/yup/blob/ff31eee8a2b10c938bb3a22544d9e33957a8cf01/src/index.ts#L43-L79","documentation":"addMethod()'s third argument is the function installed on the schema prototype; it must be a function since it will later be invoked as a schema method with `this` bound to the schema instance. If fn is missing or not callable, addMethod throws 'Method function must be provided'.","triggerScenarios":"yup.addMethod(yup.string, 'phone', undefined), passing the implementation as a non-callable (object of functions, string), or fn from an import that failed to load.","commonSituations":"Conditional imports returning undefined (SSR/build-time mismatch); wrapping implementations in objects instead of passing a single function; method defined only in some builds/feature flags.","solutions":["Pass an actual function as the third argument: yup.addMethod(yup.string, 'phone', function () { ... }).","Check the fn import/assignment resolves to a function (log typeof fn before addMethod).","Move addMethod registration so it runs after fn is defined (avoid hoisting/TLZ assumptions)."],"exampleFix":"// before\nyup.addMethod(yup.string, 'phone', validators.phone) // validators.phone undefined\n// after\nimport { phoneValidator } from './validators';\nyup.addMethod(yup.string, 'phone', phoneValidator)","handlingStrategy":"validation","validationCode":"const addFnMethod = (type, name, fn) => {\n  if (typeof fn !== 'function') throw new TypeError(`method for '${name}' must be a function, got ${typeof fn}`);\n  yup.addMethod(type, name, fn);\n};","typeGuard":"const isCallable = (v) => typeof v === 'function';","tryCatchPattern":null,"preventionTips":["Assert typeof fn === 'function' before registering, especially with dynamic imports.","Await dynamic imports before calling addMethod.","Register all custom methods in a single well-tested init file."],"tags":["yup","addmethod","argument","type-error"],"backgroundTag":"invalid-add-method-target","analyzedSha":"ff31eee8a2b10c938bb3a22544d9e33957a8cf01","analyzedAt":"2026-08-31T21:51:03.773Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}