{"id":"87cebbc758ddc3b2","repo":"babel/babel","slug":"negation-of-file-paths-is-not-supported","errorCode":null,"errorMessage":"Negation of file paths is not supported.","messagePattern":"Negation of file paths is not supported\\.","errorType":"exception","errorClass":"ConfigError","httpStatus":null,"severity":"error","filePath":"packages/babel-core/src/config/files/configuration.ts","lineNumber":200,"sourceCode":"  delete options.$schema;\n\n  return {\n    filepath,\n    dirname: path.dirname(filepath),\n    options,\n  };\n});\n\nconst readIgnoreConfig = makeStaticFileCache((filepath, content) => {\n  const ignoreDir = path.dirname(filepath);\n  const ignorePatterns = content\n    .split(\"\\n\")\n    .map(line => line.replace(/^#.*$/, \"\").trim())\n    .filter(Boolean);\n\n  for (const pattern of ignorePatterns) {\n    if (pattern.startsWith(\"!\")) {\n      throw new ConfigError(\n        `Negation of file paths is not supported.`,\n        filepath,\n      );\n    }\n  }\n\n  return {\n    filepath,\n    dirname: path.dirname(filepath),\n    ignore: ignorePatterns.map(pattern =>\n      pathPatternToRegex(pattern, ignoreDir),\n    ),\n  };\n});\n\nexport function findConfigUpwards(rootDir: string): string | null {\n  let dirname = rootDir;\n  for (;;) {","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/babel/babel/blob/06b6eae39da4ce0689fad64e2c48a6375a464208/packages/babel-core/src/config/files/configuration.ts#L182-L218","documentation":"The readIgnoreConfig loader parses a .babelignore file line by line, strips comments and blank lines, then iterates the patterns. If any pattern begins with '!' (gitignore-style negation), Babel throws a ConfigError because Babel's ignore matching is unidirectional - it does not support re-including previously ignored files. This is a deliberate limitation of the pathPatternToRegex-based matcher.","triggerScenarios":"A .babelignore file containing a line such as `!src/keep.js` intended to un-ignore a file that an earlier pattern excluded.","commonSituations":"Developers familiar with .gitignore syntax who try to reuse negation patterns in .babelignore; migrating a .gitignore to .babelignore by copy-paste.","solutions":["Remove all lines starting with '!' from .babelignore; Babel ignore is additive only.","Restructure ignore patterns so that the file you wanted to re-include is simply not matched by any ignore pattern (use more specific exclude patterns instead).","If you need conditional inclusion logic, use the per-file `ignore`/`only` functions in babel.config.js instead of .babelignore."],"exampleFix":"// before - .babelignore throws error 26\nbuild/\n!src/runtime.js\n\n// after - no negation; narrow the ignore instead\nbuild/\nsrc/generated/","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nif (fs.existsSync('.babelignore')) {\n  const lines = fs.readFileSync('.babelignore', 'utf8').split('\\n');\n  const negated = lines.filter(l => l.replace(/#.*/, '').trim().startsWith('!'));\n  if (negated.length) throw new Error('.babelignore does not support negation: ' + negated.join(', '));\n}","typeGuard":"function hasNoNegation(patterns: string[]): boolean {\n  return patterns.every(p => !p.trim().startsWith('!'));\n}","tryCatchPattern":"try { babel.transformFileSync(file); }\ncatch (err) {\n  if (/Negation of file paths is not supported/.test(err.message)) {\n    console.error('Remove lines starting with ! from', err.filename);\n  }\n  throw err;\n}","preventionTips":["Treat .babelignore as additive-only; do not reuse .gitignore with negations.","For conditional inclusion, use the `ignore` function option in babel.config.js.","Lint .babelignore in CI for leading-! lines."],"tags":["config","ignore","babelignore","validation"],"analyzedSha":"06b6eae39da4ce0689fad64e2c48a6375a464208","analyzedAt":"2026-08-03T20:13:43.465Z","schemaVersion":2}