Skip to content

Troubleshooting

Common problems and how to resolve them.

Before diving into specific issues, run the built-in diagnostics:

Terminal window
npx @santi020k/eslint-config-basic doctor

doctor checks for missing config files, configs that cannot be loaded, lingering v1 imports, missing lint scripts, workspace packages not covered by projects, and parallel ESLint version copies. It also checks whether Astro Doctor is paired with Astro and whether its installed package supports the current Node.js and ESLint versions.

For automation, use structured output:

Terminal window
npx @santi020k/eslint-config-basic doctor --json
Terminal window
npx @santi020k/eslint-config-basic explain

explain prints every detected input so you can confirm what the composer will receive before anything is written.


Version 3 keeps @santi020k/eslint-config-basic lean. A detected framework must have its config package installed, and optional features require their category packs.

Terminal window
pnpm add -D @santi020k/eslint-config-react
pnpm add -D @santi020k/eslint-config-libraries

The thrown error names the missing config package. Run basic-eslint explain to see why it was detected. If you prefer every supported package to be installed together, switch to @santi020k/eslint-config-full.


A framework I did not enable is being linted

Section titled “A framework I did not enable is being linted”

Auto-detection reads package.json and enables installed optional framework configs for packages it finds. To disable this:

import { defineConfig } from '@santi020k/eslint-config-basic'
export default await defineConfig({
autoFrameworks: false,
frameworks: {
react: true
}
})

Or disable only framework detection while keeping other categories automatic:

export default await defineConfig({
detection: { frameworks: false },
frameworks: { react: true }
})

Detected frameworks override my explicit config

Section titled “Detected frameworks override my explicit config”

By default, detected and explicit values are merged (optionMergeStrategy: 'merge'). Use 'replace' to make your explicit object the sole source:

export default await defineConfig({
frameworks: { react: true },
optionMergeStrategy: 'replace'
})

The TypeScript projectService rejects files not covered by a tsconfig.json.

Make sure the file belongs in the project’s tsconfig.json and check its include/exclude patterns. Detection and TypeScript roots normally follow the config directory; set root only when your project root differs.

For templates or tooling files that intentionally sit outside the TypeScript project, use syntax-only linting for those files:

import { defineConfig } from '@santi020k/eslint-config-basic'
export default await defineConfig({
typescript: {
untypedFiles: ['templates/**/*.ts']
}
})

TypeScript config files (**/*.config.{ts,mts,cts}) already receive this fallback. Set untypedFiles: false when every TypeScript file must have type information. See project roots and syntax-only files and Monorepo for package-specific roots.


ESLint times out with Atomics.wait() failed: timed-out

Section titled “ESLint times out with Atomics.wait() failed: timed-out”

Tailwind CSS v4 uses a heavy initialization process in worker threads. Provide an explicit entryPoint:

import { defineConfig, Library } from '@santi020k/eslint-config-basic'
export default [
...await defineConfig({ libraries: [Library.Tailwind] }),
{
name: 'project/tailwind-settings',
settings: {
'better-tailwindcss': {
entryPoint: './src/index.css'
}
}
}
]

If timeouts persist, increase the worker timeout:

Terminal window
SYNCKIT_TIMEOUT=60000 eslint . --max-warnings=0

Direct calls from eslint.config.* anchor detection to the config directory, even when ESLint starts elsewhere. When the intended project root differs, set root to that directory. For a config stored one folder below the project root:

import { resolve } from 'node:path'
import { defineConfig } from '@santi020k/eslint-config-basic'
export default await defineConfig({
root: resolve(import.meta.dirname, '..')
})

doctor warns when two different ESLint copies are installed. The current release line supports ESLint 10, so align your app and workspace packages on the same ESLint 10 version. With pnpm, use overrides:

{
"pnpm": {
"overrides": {
"eslint": "$eslint"
}
}
}

Then run pnpm install to deduplicate.


VS Code does not pick up flat config rules

Section titled “VS Code does not pick up flat config rules”

Install the Microsoft ESLint extension and use the workspace’s installed ESLint 10. Flat config is mandatory in ESLint 10; the extension ignores eslint.useFlatConfig for this version.

Check the ESLint output channel for the loaded library, Node runtime, and config errors. In a workspace with package-owned configs, configure working directories as shown in the editor and CI recipe. After installing dependencies or changing settings, restart the ESLint server.


defineConfig is not a function or import error

Section titled “defineConfig is not a function or import error”

The named v3 factory is defineConfig:

import { defineConfig } from '@santi020k/eslint-config-basic'
export default defineConfig()

The zero-argument call anchors detection to this config file, independently of the ESLint process’s working directory. Feature factories must be imported from their category package, the compatibility @santi020k/eslint-config-integrations aggregate, or @santi020k/eslint-config-full—not from the lean basic root.

ESLint cannot find the plugin for an override rule

Section titled “ESLint cannot find the plugin for an override rule”

Pass overrides to defineConfig() so the composer can attach already-loaded plugins to the rule blocks that reference them:

import { defineConfig } from '@santi020k/eslint-config-basic'
export default await defineConfig({}, {
files: ['src/**/*.ts'],
rules: { '@typescript-eslint/no-unused-vars': 'error' }
})

The example assumes TypeScript is detected and enabled. If you append overrides after composition, wrap the final array with attachReferencedPlugins(). That helper reuses plugins registered in the array; a new plugin still needs an explicit import and plugins registration. See local overrides for both patterns.

Use the inspector to find which config block sets the rule last:

Terminal window
pnpm run inspector

Did this page help?

Your answer stays in this browser. Share details on GitHub to help improve the docs.