{"record":{"id":"09ea9ec0790f071d","repo":"jquense/yup","slug":"exclusive-tests-must-provide-a-unique-name-ident","errorCode":null,"errorMessage":"Exclusive tests must provide a unique `name` identifying the test","messagePattern":"Exclusive tests must provide a unique `name` identifying the test","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/schema.ts","lineNumber":794,"sourceCode":"      opts = { name: args[0], test: args[1] };\n    } else {\n      opts = { name: args[0], message: args[1], test: args[2] };\n    }\n\n    if (opts.message === undefined) opts.message = locale.default;\n\n    if (typeof opts.test !== 'function')\n      throw new TypeError('`test` is a required parameters');\n\n    let next = this.clone();\n    let validate = createValidation(opts);\n\n    let isExclusive =\n      opts.exclusive || (opts.name && next.exclusiveTests[opts.name] === true);\n\n    if (opts.exclusive) {\n      if (!opts.name)\n        throw new TypeError(\n          'Exclusive tests must provide a unique `name` identifying the test',\n        );\n    }\n\n    if (opts.name) next.exclusiveTests[opts.name] = !!opts.exclusive;\n\n    next.tests = next.tests.filter((fn) => {\n      if (fn.OPTIONS!.name === opts.name) {\n        if (isExclusive) return false;\n        if (fn.OPTIONS!.test === validate.OPTIONS.test) return false;\n      }\n      return true;\n    });\n\n    next.tests.push(validate);\n\n    return next;\n  }","sourceCodeStart":776,"sourceCodeEnd":812,"githubUrl":"https://github.com/jquense/yup/blob/ff31eee8a2b10c938bb3a22544d9e33957a8cf01/src/schema.ts#L776-L812","documentation":"Exclusive tests (which replace any same-named test rather than running alongside it) must have a `name` so they can be identified and replaced. This TypeError is thrown when opts.exclusive is true but no name was provided.","triggerScenarios":"Calling .test({ exclusive: true, test: fn }) or .test(undefined, 'msg', fn, true) without a name; the fourth positional argument sets exclusive but the first (name) is missing.","commonSituations":"Setting exclusive: true to override a built-in/default test but forgetting the name; copying the positional-args signature and passing true as the 4th argument without a name string.","solutions":["Add a unique name: .test({ name: 'myTest', exclusive: true, test: fn })","If no overriding is intended, remove exclusive: true","Match the built-in test's name exactly if the goal is to override it"],"exampleFix":"// before\nyup.number().test({ exclusive: true, test: v => v < 100 });\n// after\nyup.number().test({ name: 'lessThan100', exclusive: true, test: v => v < 100 });","handlingStrategy":"validation","validationCode":"if (opts.exclusive && !opts.name) throw new Error('exclusive tests need a name');\nschema.test({ name: 'myTest', exclusive: true, test: fn });","typeGuard":"function isValidExclusiveTest(o: { exclusive?: boolean; name?: string }): boolean {\n  return !o.exclusive || typeof o.name === 'string' && o.name.length > 0;\n}","tryCatchPattern":"try { schema.test(opts); } catch (e) { if (/Exclusive tests/.test(e.message)) schema.test({ ...opts, name: opts.name ?? 'anonTest' }); else throw e; }","preventionTips":["Always name custom tests, even non-exclusive ones","Match built-in test names exactly when overriding them","Review the 4-argument positional form; prefer the options object"],"tags":["api-misuse","typeerror","custom-test"],"backgroundTag":"missing-required-argument","analyzedSha":"ff31eee8a2b10c938bb3a22544d9e33957a8cf01","analyzedAt":"2026-08-31T21:51:03.773Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}