{"id":"7ad51098a01905d9","repo":"eslint/eslint","slug":"schema-for-rule-rulename-is-invalid-err-mess","errorCode":null,"errorMessage":"Schema for rule ${ruleName} is invalid: ${err.message}","messagePattern":"Schema for rule (.+?) is invalid: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/rule-tester/rule-tester.js","lineNumber":1272,"sourceCode":"\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(\"\\n\");\n\n\t\t\t\t\tthrow new Error([\n\t\t\t\t\t\t`Schema for rule ${ruleName} is invalid:`,\n\t\t\t\t\t\terrors,\n\t\t\t\t\t]);\n\t\t\t\t}\n\n\t\t\t\t/*\n\t\t\t\t * `ajv.validateSchema` checks for errors in the structure of the schema (by comparing the schema against a \"meta-schema\"),\n\t\t\t\t * and it reports those errors individually. However, there are other types of schema errors that only occur when compiling\n\t\t\t\t * the schema (e.g. using invalid defaults in a schema), and only one of these errors can be reported at a time. As a result,\n\t\t\t\t * the schema is compiled here separately from checking for `validateSchema` errors.\n\t\t\t\t */\n\t\t\t\ttry {\n\t\t\t\t\tajv.compile(schema);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Schema for rule ${ruleName} is invalid: ${err.message}`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcause: err,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// check for validation errors\n\t\t\ttry {\n\t\t\t\tconfigs.normalizeSync();\n\t\t\t\tconfigs.getConfig(\"test.js\");\n\t\t\t} catch (error) {\n\t\t\t\terror.message = `ESLint configuration in rule-tester is invalid: ${error.message}`;\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\t// Verify the code.","sourceCodeStart":1254,"sourceCodeEnd":1290,"githubUrl":"https://github.com/eslint/eslint/blob/f131c034ad91bbf06bcbb6b5e931447a8e419a46/lib/rule-tester/rule-tester.js#L1254-L1290","documentation":"Thrown during RuleTester.run() at lib/rule-tester/rule-tester.js:1272 when `ajv.validateSchema(schema)` passed (the schema is structurally well-formed) but `ajv.compile(schema)` throws. Compile-time errors are problems that only surface when ajv turns the schema into a validator — most commonly invalid `default` values that fail their own schema, cyclic or unresolvable `$ref`s, or keyword misuses that pass meta-validation but break compilation. The original error is attached as `cause`.","triggerScenarios":"A rule's `meta.schema` includes a `default` value that does not validate against its own constraints (e.g. `default: 5` with `type: \"string\"`), an unresolvable `$ref`, or another structural issue that only fails at compile time. RuleTester compiles the schema explicitly after the structural check to surface exactly one such error.","commonSituations":"Adding a `default` that contradicts the keyword's type/enum; renaming a definition but forgetting to update the `$ref`; using a keyword from a draft ajv isn't configured for; schema regression after a refactor.","solutions":["Inspect `err.message` (and the `cause`) in the thrown error — it typically names the failing keyword or default.","Make every `default` validate against its own subschema (e.g. for `enum: [\"a\",\"b\"]`, the default must be one of those).","Resolve/inline any `$ref` and confirm referenced definitions exist and are not cyclic in an unsupported way.","Compile the schema in isolation to iterate faster: `try { ajv.compile(yourSchema) } catch (e) { console.error(e.message); }`."],"exampleFix":"// before\nmeta: {\n  schema: [{\n    enum: [\"always\", \"never\"],\n    default: \"sometimes\"\n  }]\n}\n\n// after\nmeta: {\n  schema: [{\n    enum: [\"always\", \"never\"],\n    default: \"always\"\n  }]\n}","handlingStrategy":"validation","validationCode":"const Ajv = require('ajv');\nfunction compileStandalone(schema) {\n  const ajv = new Ajv();\n  ajv.validateSchema(schema); // structural first\n  if (ajv.errors) throw new Error('structural: ' + ajv.errorsText(ajv.errors));\n  try { ajv.compile(schema); } // compile-time (defaults, refs)\n  catch (e) { throw new Error('compile: ' + e.message); }\n}","typeGuard":"/** @param {object} schema */\nfunction defaultsValidateAgainstSelf(schema) {\n  const check = (node) => {\n    if (!node || typeof node !== 'object') return true;\n    if ('default' in node) {\n      if ('enum' in node && !node.enum.includes(node.default)) return false;\n      if (node.type === 'string' && typeof node.default !== 'string') return false;\n      if (node.type === 'number' && typeof node.default !== 'number') return false;\n      if (node.type === 'boolean' && typeof node.default !== 'boolean') return false;\n    }\n    return Object.values(node).every(check);\n  };\n  return check(schema);\n}","tryCatchPattern":null,"preventionTips":["Ensure every `default` satisfies its own `type`/`enum`/constraints.","Keep `$ref` targets in-schema and acyclic (or supported-cyclic).","Compile schemas in isolation during development for faster, clearer errors."],"tags":["rule-tester","schema","ajv","compile","default","custom-rules"],"analyzedSha":"f131c034ad91bbf06bcbb6b5e931447a8e419a46","analyzedAt":"2026-08-03T19:53:24.025Z","schemaVersion":2}