web-infra-dev / web-infra-dev/rslint
[Bug]: Unknown rules in configuration are silently ignored instead of throwing configuration errors
- Dominant language
- Go
- Stars
- 459
- Forks
- 33
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 376
Description
### Details
When an unknown, misspelled, or unregistered rule (e.g., `'non-existent-rule-name': 'error'`) is specified in `rslint.config.ts`, `rslint` silently ignores the rule. It does not warn the developer or fail the build, which can lead to situations where intended lint checks are never actually executed due to silent typos.
In contrast, **ESLint** performs strict configuration validation at startup and crashes loudly, preventing developers from continuing with invalid configurations.
---
### Detailed Linter Behavior Comparison
#### **rslint Behavior**
- Running `rslint` with an unknown rule succeeds silently.
- The rule is skipped entirely without any logs or diagnostics.
- Example:
```bash
$ npx rslint
Found 0 errors and 0 warnings (linted 542 files with 9 rules in 2.158s using 8 threads)
```
#### **ESLint Behavior**
ESLint strictly validates rules and plugins at start time and throws errors, unless the rule is set to `"off"` or `0`:
1. **Unknown core rule**:
```
TypeError: Key "rules": Key "non-existent-rule-name": Could not find "non-existent-rule-name" in plugin "@".
```
2. **Plugin rule where the plugin is not registered**:
```
A configuration object specifies rule "some-plugin/non-existent-rule", but could not find plugin "some-plugin".
```
3. **Plugin rule where the plugin is registered, but the rule does not exist**:
```
TypeError: Key "rules": Key "some-plugin/non-existent-rule": Could not find "some-plugin/non-existent-rule" in plugin "some-plugin".
```
> [!NOTE]
> If the unknown/unregistered rule is explicitly set to `"off"` (or `0`), ESLint **bypasses validation** and runs successfully (exit code 0).
---
### Steps to Reproduce
1. In `rslint.config.ts`, add an unknown rule with a non-zero severity (e.g. `'error'` or `'warn'`):
```ts
export default defineConfig([
{
files: ['**/*.ts'],
rules: {
'non-existent-rule-name': 'error',
'import-x/this-rule-does-not-exist': 'error',
}
}
])
```
2. Run `npx rslint`.
3. Observe that the linter completes successfully with `exit code 0`, completely ignoring the invalid rule keys.
---
### Expected Behavior
`rslint` should perform config validation at startup:
- Match rule names against natively implemented Go rules.
- Match rule names with plugin namespaces against the loaded plugin metadata returned from the worker initialization.
- If a rule name cannot be resolved in either registry, `rslint` should report a configuration error and fail non-zero (or at least output a warning).
- **Parity with ESLint**: Validation checks should only run on rules that are enabled (severity is not `'off'` or `0`), matches ESLint's behavior of silently ignoring unknown rules when disabled.
Contributor guide
Research direction
Start by reproducing the issue with the shown rslint.config.ts example and npx rslint. Inspect configuration validation around native Go rules, worker initialization, and loaded plugin metadata. Done means enabled unknown core and plugin rules produce a configuration error and nonzero exit, while rules set to off or 0 remain ignored.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100