Skip to content

feat!: add meta.languages to JSON rules#238

Open
Pixel998 wants to merge 4 commits into
mainfrom
feat/add-meta-languages-to-rules
Open

feat!: add meta.languages to JSON rules#238
Pixel998 wants to merge 4 commits into
mainfrom
feat/add-meta-languages-to-rules

Conversation

@Pixel998
Copy link
Copy Markdown
Contributor

Prerequisites checklist

AI acknowledgment

  • I did not use AI to generate this PR.
  • (If the above is not checked) I have reviewed the AI-generated content before submitting.

What is the purpose of this pull request?

This PR adds meta.languages to rules, following the decision made during the TSC meeting on 16-Apr-2026.

What changes did you make? (Give an overview)

Added meta.languages to rule definitions and meta.docs.dialects to their docs metadata.

Related Issues

eslint/eslint#20716 (comment)

Is there anything you'd like reviewers to focus on?

@eslintbot eslintbot added this to Triage May 10, 2026
@github-project-automation github-project-automation Bot moved this to Needs Triage in Triage May 10, 2026
@lumirlumir lumirlumir moved this from Needs Triage to Triaging in Triage May 11, 2026
@lumirlumir lumirlumir moved this from Triaging to Evaluating in Triage May 11, 2026
Copy link
Copy Markdown
Member

@lumirlumir lumirlumir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After further investigation, I've found that this change could lead to a breaking change for end-users in a way different from what was mentioned in Markdown.

For instance, if we use the default setup described in the README.md as shown below, it works correctly.

// eslint.config.js
import { defineConfig } from "eslint/config";
import json from "@eslint/json";

export default defineConfig([
	{
		plugins: {
			json,
		},
	},

	// lint JSON files
	{
		files: ["**/*.json"],
		language: "json/json",
		rules: {
			"json/no-duplicate-keys": "error",
		},
	},

	// lint JSONC files
	{
		files: ["**/*.jsonc", ".vscode/*.json"],
		language: "json/jsonc",
		rules: {
			"json/no-duplicate-keys": "error",
		},
	},

	// lint JSON5 files
	{
		files: ["**/*.json5"],
		language: "json/json5",
		rules: {
			"json/no-duplicate-keys": "error",
		},
	},
]);

However, what if a user prefers a different namespace, such as eslintjson, instead of json?

Suppose we have a configuration like the one below, which uses the eslintjson namespace:

// eslint.config.js
import { defineConfig } from "eslint/config";
import eslintjson from "@eslint/json";

export default defineConfig([
	{
		plugins: {
			eslintjson,
		},
	},

	// lint JSON files
	{
		files: ["**/*.json"],
		language: "eslintjson/json",
		rules: {
			"eslintjson/no-duplicate-keys": "error",
		},
	},

	// lint JSONC files
	{
		files: ["**/*.jsonc", ".vscode/*.json"],
		language: "eslintjson/jsonc",
		rules: {
			"eslintjson/no-duplicate-keys": "error",
		},
	},

	// lint JSON5 files
	{
		files: ["**/*.json5"],
		language: "eslintjson/json5",
		rules: {
			"eslintjson/no-duplicate-keys": "error",
		},
	},
]);

The newly added languages: ["json/json", "json/jsonc", "json/json5"] field prevents the above configuration from working and throws an error like this:

Oops! Something went wrong! :(

ESLint: 10.3.0

The following rules do not support the language "eslintjson/json":
        - "eslintjson/no-empty-keys"

To fix this error, either:
- Remove the rule from your configuration, or set its severity to "off".
- Use the "files" option to apply the rule only to files of the supported language, for example:
  {
    files: ["**/*.js"],
    rules: { "eslintjson/no-empty-keys": "error" }
  }

See https://eslint.org/docs/latest/use/configure/rules for more information.

Before adding the languages field, this configuration worked correctly. It only fails after the addition of the languages field.


It seems this implies that the newly added languages field restricts the namespace to only those explicitly described. Previously, users were not restricted by the namespace used in the rule, allowing them to use eslintjson, eslintcorejson, or any other prefix they preferred instead of json.

For example, if a user uses two different JSON plugins, such as eslint-plugin-json, they might want to use distinct namespaces for each—like json1/rule-name for @eslint/json and json2/rule-name for eslint-plugin-json.

This change could potentially break that scenario.

@DMartens
Copy link
Copy Markdown

The problem lumir mentioned could be solved if the core normalizes the language id by using plugin.meta.name (here "@eslint/json") instead of the plugin id.
This normalization would be similar to the plugin name inference in eslintrc's plugin (e.g. for scoped packages only the package name, which would be "json").

@nzakas
Copy link
Copy Markdown
Member

nzakas commented May 12, 2026

Yes, this is a bug in the core implementation. It should normalize the namespace used for language resolution. Can you open a bug for that?

@lumirlumir
Copy link
Copy Markdown
Member

It seems like an issue hasn't been opened yet. I can open one.

Copy link
Copy Markdown
Member

@fasttime fasttime left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add namespace: "json" in the plugin's meta object to avoid the problem described in #238 (review).

json/src/index.js

Lines 20 to 23 in 720c43d

meta: {
name: "@eslint/json",
version: "1.2.0", // x-release-please-version
},

Copy link
Copy Markdown
Member

@lumirlumir lumirlumir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would also be helpful to add an integration test in tests/plugin/eslint.test.js to verify the behavior mentioned in #238 (review) and prevent any potential regressions.

https://github.com/eslint/json/blob/main/tests/plugin/eslint.test.js

Comment thread package.json
"c8": "^11.0.0",
"dedent": "^1.5.3",
"eslint": "^10.0.0",
"eslint": "^10.4.0",
Copy link
Copy Markdown
Contributor Author

@Pixel998 Pixel998 May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated ESLint so the test runs with meta.languages enforcement, which was added in 10.2.0.

Copy link
Copy Markdown
Member

@fasttime fasttime left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR should be considered a breaking change for this plugin and tagged as feat!, because it may break compatibility with existing configs, even if that's a desired effect. Other than that, the changes LGTM.

Copy link
Copy Markdown
Member

@lumirlumir lumirlumir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

I think this PR should be considered a breaking change for this plugin and tagged as feat!, because it may break compatibility with existing configs, even if that's a desired effect.

While I can no longer find a certain failure scenario with this setup, there might be some edge cases we’re all missing. I think it may make sense to defer this change to the next major version for safety.

@lumirlumir lumirlumir changed the title feat: add meta.languages to JSON rules feat!: add meta.languages to JSON rules May 20, 2026
@lumirlumir lumirlumir moved this from Evaluating to Blocked in Triage May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Blocked

Development

Successfully merging this pull request may close these issues.

6 participants