{"record":{"id":"47c0ff589a398c50","repo":"OpenRefine/OpenRefine","slug":"throw-new-validationerror-verrors","errorCode":null,"errorMessage":" throw new ValidationError(vErrors); ","messagePattern":" throw new ValidationError\\(vErrors\\); ","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"extensions/wikibase/module/scripts/ajv.js","lineNumber":2794,"sourceCode":"    }\n    out += ' if (!' + ($valid) + ') {   var err =   '; /* istanbul ignore else */\n    if (it.createErrors !== false) {\n      out += ' { keyword: \\'' + ('if') + '\\' , dataPath: (dataPath || \\'\\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { failingKeyword: ' + ($ifClause) + ' } ';\n      if (it.opts.messages !== false) {\n        out += ' , message: \\'should match \"\\' + ' + ($ifClause) + ' + \\'\" schema\\' ';\n      }\n      if (it.opts.verbose) {\n        out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';\n      }\n      out += ' } ';\n    } else {\n      out += ' {} ';\n    }\n    out += ';  if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';\n    if (!it.compositeRule && $breakOnError) {\n      /* istanbul ignore if */\n      if (it.async) {\n        out += ' throw new ValidationError(vErrors); ';\n      } else {\n        out += ' validate.errors = vErrors; return false; ';\n      }\n    }\n    out += ' }   ';\n    if ($breakOnError) {\n      out += ' else { ';\n    }\n  } else {\n    if ($breakOnError) {\n      out += ' if (true) { ';\n    }\n  }\n  return out;\n}\n\n},{}],27:[function(require,module,exports){\n'use strict';","sourceCodeStart":2776,"sourceCodeEnd":2812,"githubUrl":"https://github.com/OpenRefine/OpenRefine/blob/a946177e049f3b0644261661db36cbb0c81ccf8a/extensions/wikibase/module/scripts/ajv.js#L2776-L2812","documentation":"ajv code-generation template (bundled ajv.js in the Wikibase extension) at the end of a generated custom-rule/keyword check: when the rule records an error and fail-fast is active in an async schema, the generated code executes `throw new ValidationError(vErrors)` — throwing the accumulated `Ajv.ValidationError` to the caller instead of returning false.","triggerScenarios":"A custom keyword or rule validation fails while running a compiled async validator; because `!it.compositeRule && $breakOnError`, the emitted code throws `new ValidationError(vErrors)` with all errors collected so far.","commonSituations":"Schemas using custom ajv keywords (format, user-defined rules) inside async validation; plugin/bundled contexts (like the Wikibase extension) where the throw surfaces as an unexpected exception from `validate()`.","solutions":["Handle the throw with try/catch and use `e.errors` for diagnostics.","Enable `allErrors: true` on the Ajv instance to avoid the fail-fast throw.","Verify the custom keyword's validate function; fix its inputs or its error reporting.","Make the schema synchronous if the custom keyword is not truly async."],"exampleFix":"// before\nconst result = await validate(item); // throws ValidationError from custom keyword\n\n// after\nconst ajv = new Ajv({ allErrors: true }); // collect errors, return false instead of throw\nconst validate = await ajv.compileAsync(schema);","handlingStrategy":"try-catch","validationCode":"// Pre-screen with a sync dry-run to catch custom-keyword violations early:\nconst dry = new Ajv({ allErrors: true });\ndry.addKeyword('myKeyword', { validate: mySyncProxy });\nif (!dry.validate(schemaWithoutAsync, data)) console.warn(dry.errors);","typeGuard":"function isAjvValidationError(e) { return e instanceof Error && Array.isArray(e.errors) && typeof e.message === 'string'; }","tryCatchPattern":"try {\n  await validate(item);\n} catch (e) {\n  if (isAjvValidationError(e)) handleInvalidItem(item, e.errors);\n  else throw e;\n}","preventionTips":["Test custom keywords with known-bad inputs before production use.","Enable `allErrors: true` so custom-keyword failures don't short-circuit with a throw.","Keep custom keyword `validate` functions pure and side-effect free.","Wrap every async `validate()` call site in a shared helper that normalizes errors."],"tags":["ajv","json-schema","custom-keyword","async"],"backgroundTag":"schema-validation-failed","analyzedSha":"a946177e049f3b0644261661db36cbb0c81ccf8a","analyzedAt":"2026-09-08T10:21:27.735Z","contentChangedAt":"2026-09-08T10:21:27.735Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}