eslint/eslint · error

Key "rules": Key "${ruleId}":

Error message

Key "rules": Key "${ruleId}":

What it means

Thrown in validateRulesConfig() (config.js:728) when the per-rule ajv validator runs against the rule's configured options and reports errors. The message is prefixed 'Key "rules": Key "<ruleId>":' followed by each ajv error (value, message, and for additionalProperties the expected properties). This is the standard 'rule options do not match the rule's schema' error.

Source

Thrown at lib/config/config.js:728

			// Check if the rule supports the current language
			if (
				!doesRuleSupportLanguage(
					rule.meta?.languages,
					normalizedLanguageName,
					validPluginNames,
				)
			) {
				unsupportedLanguageRules.push(ruleId);
			}

			const validateRule = getOrCreateValidator(rule, ruleId);

			if (validateRule) {
				validateRule(ruleOptions.slice(1));

				if (validateRule.errors) {
					throw new Error(
						`Key "rules": Key "${ruleId}":\n${validateRule.errors
							.map(error => {
								if (
									error.keyword === "additionalProperties" &&
									error.schema === false &&
									typeof error.parentSchema?.properties ===
										"object" &&
									typeof error.params?.additionalProperty ===
										"string"
								) {
									const expectedProperties = Object.keys(
										error.parentSchema.properties,
									).map(property => `"${property}"`);

									return `\tValue ${JSON.stringify(error.data)} ${error.message}.\n\t\tUnexpected property "${error.params.additionalProperty}". Expected properties: ${expectedProperties.join(", ")}.\n`;
								}

								return `\tValue ${JSON.stringify(error.data)} ${error.message}.\n`;

View on GitHub (pinned to f131c034ad)

Solutions

  1. Read the full message: it names the value, the failing keyword, and (for extra props) the allowed properties.
  2. Open the rule's docs/schema and align your options array to the expected shape and types.
  3. If you intended no options, configure the rule as a bare severity (e.g. 'error') without an options array.
  4. Disable the rule (severity 0) only as a last resort; it skips validation entirely.

Example fix

// before
{ 'quotes': ['error', 'single', { avoidEscape: 'yes' }] }

// after
{ 'quotes': ['error', 'single', { avoidEscape: true }] }
Defensive patterns

Strategy: try-catch

Validate before calling

function ruleOptionsMatch(ruleId, rule, options) {
  const schema = rule?.meta?.schema;
  if (!schema) return true;
  // Use ajv against schema with the options array; returns true/false.
}

Type guard

null

Try / catch

try {
  config.validateRulesConfig(rules);
} catch (e) {
  if (/^Key "rules":/.test(e.message)) {
    console.error('Rule options invalid:\n' + e.message);
  } else throw e;
}

Prevention

When it happens

Trigger: Configuring a rule with options that violate its meta.schema: wrong types, out-of-range enums, extra properties when additionalProperties is false, wrong array length, etc. Reached for enabled (non-zero) rules after defaultOptions are merged.

Common situations: Passing a string where a number is expected; typo'd option names; using options from a different rule version; passing options to a rule whose schema is `[]` (no options allowed).

Related errors


AI-assisted analysis of eslint/eslint@f131c034ad (2026-08-03). Data as JSON: /data/errors/e427773a725fabd8.json. Report an issue: GitHub.