{"record":{"id":"2e3b37d39177b60c","repo":"hapijs/joi","slug":"result-error-details-0-message","errorCode":null,"errorMessage":"result.error.details[0].message","messagePattern":"result\\.error\\.details\\[0\\]\\.message","errorType":"validation","errorClass":"AssertError","httpStatus":null,"severity":"error","filePath":"lib/common.js","lineNumber":79,"sourceCode":"};\n\n\nexports.assertOptions = function (options, keys, name = 'Options') {\n\n    Assert(options && typeof options === 'object' && !Array.isArray(options), 'Options must be of type object');\n    const unknownKeys = Object.keys(options).filter((k) => !keys.includes(k));\n    Assert(unknownKeys.length === 0, `${name} contain unknown keys: ${unknownKeys}`);\n};\n\n\nexports.checkPreferences = function (prefs) {\n\n    Schemas = Schemas || require('./schemas');\n\n    const result = Schemas.preferences.validate(prefs);\n\n    if (result.error) {\n        throw new AssertError([result.error.details[0].message]);\n    }\n};\n\n\nexports.compare = function (a, b, operator) {\n\n    switch (operator) {\n        case '=': return a === b;\n        case '>': return a > b;\n        case '<': return a < b;\n        case '>=': return a >= b;\n        case '<=': return a <= b;\n    }\n};\n\n\nexports.default = function (value, defaultValue) {\n","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/hapijs/joi/blob/58ce83e919a14f481f1a1edf30ee212cf90ba6a4/lib/common.js#L61-L97","documentation":"joi's assertPreferences(prefs) validates a preferences object against Schemas.preferences and throws an AssertError carrying the first validation message from result.error.details (lib/common.js:79). It means the preferences object you passed to .validate(prefs) / .match(prefs) etc. contains keys or values joi does not accept. The actual problem is inside AssertError.details — the message text names the offending key.","triggerScenarios":"Calling any API that accepts preferences with an invalid value, e.g. schema.validate(value, { abortEarly: 'yes' }) (string instead of boolean), { errors: { label: 42 } }, { wrap: { string: 'bad' } }, unknown keys like { stripUnkown: true } (typo), or passing a non-object.","commonSituations":"Typo'd preference keys (stripUnkown vs stripUnknown), wrong types after refactoring from string constants to enums, values copied from joi v13/v14 docs that were removed/renamed in newer versions, and preferences built dynamically from config/env where types are strings.","solutions":["Read the message from the thrown error: catch it and inspect err.details / err.preferences — it names the offending key and expected type.","Fix the offending preference key/value per that message, e.g. abortEarly must be a boolean.","Validate prefs yourself first with Schemas.preferences.validate(prefs) during development to get the full details array instead of only the first message.","If the preference comes from config/env, coerce types before passing (e.g. abortEarly: process.env.ABORT_EARLY !== 'false')."],"exampleFix":"// before\nconst result = schema.validate(value, { abortEarly: 'false', stripUnkown: true });\n// after\nconst result = schema.validate(value, { abortEarly: false, stripUnknown: true });","handlingStrategy":"validation","validationCode":"const Joi = require('joi');\nconst prefs = { abortEarly: false, stripUnknown: true };\nconst check = Joi.object({\n  abortEarly: Joi.boolean(),\n  stripUnknown: Joi.boolean(),\n  errors: Joi.object(),\n  wrap: Joi.object(),\n  messages: Joi.object()\n}).unknown(false).validate(prefs);\nif (check.error) throw new Error('Bad joi preferences: ' + check.error.details.map(d => d.message).join('; '));","typeGuard":"function isValidPrefs(prefs) {\n  return typeof prefs === 'object' && prefs !== null && !Array.isArray(prefs);\n}","tryCatchPattern":"try {\n  const result = schema.validate(value, prefs);\n} catch (err) {\n  if (err.name === 'AssertError' && Array.isArray(err.details)) {\n    throw new Error('Invalid validate() preferences: ' + err.details.join('; '));\n  }\n  throw err;\n}","preventionTips":["Never hand-build preference objects from raw config strings without type coercion.","Use a named constant/shared defaults object for validate options instead of inline literals.","After upgrading joi, run preferences through a validation smoke test — options get renamed/removed between majors.","Watch for common typos: stripUnknown (not stripUnkown), errors.label values like 'path' | 'key'."],"tags":["validation","preferences","configuration"],"backgroundTag":"invalid-joi-preferences","analyzedSha":"58ce83e919a14f481f1a1edf30ee212cf90ba6a4","analyzedAt":"2026-09-01T18:09:30.061Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}