You review the Codex PR. New component uses React.FC<Props>. Another file imports componentWillMount. A third uses useEffect with a callback that returns a Promise. None of these are quite wrong — they all “work” — but React.FC is discouraged since React 18, componentWillMount is deprecated since React 16.3, and async effects leak. Your existing code does not use any of these patterns; Codex injected them.
The cause is training data lag. Codex was trained on a snapshot of code from before some of these patterns fell out of favor. Left alone, it writes idiomatic-for-2019 React, idiomatic-for-2015 Node, idiomatic-for-Python-2 type hints. The fix is a combination of explicit AGENTS.md rules, ESLint deprecation enforcement, and pointing the agent at current docs.
Common causes
1. Training data predates the deprecation
React.FC was Trends-trending in 2019, lost favor around 2021. Models trained on pre-2022 GitHub still produce it. Similarly: componentWillMount, componentWillReceiveProps, jQuery, var, Python 2 print statements, Node request library.
How to spot it: Diff includes patterns the rest of your codebase does not use. grep your repo for the new pattern — if you find zero occurrences elsewhere, Codex pulled it from training data.
2. No AGENTS.md guidance on framework versions
Codex does not know which React, Node, Python, or framework version you target. It picks the most common pattern from training, which may match your version or not.
How to spot it: grep -i 'version\|deprecated\|prefer\|avoid' AGENTS.md returns nothing on framework conventions.
3. ESLint is configured but does not enforce deprecation
You have ESLint but no eslint-plugin-react or eslint-plugin-deprecation. The agent’s output passes lint while using ancient APIs.
How to spot it: npm run lint succeeds on the agent’s PR despite obvious deprecated code.
4. Agent referenced an outdated tutorial in your README
Your README.md or docs/setup.md still shows class extends React.Component with componentWillMount. Codex saw it as “house style” and copied it.
How to spot it: grep -rn 'componentWillMount\|React.FC\|var ' README.md docs/ returns matches.
5. Codex used a popular but stale npm package
It added request, moment, node-fetch@2, or uuid@3 — all popular packages now considered deprecated or superseded. The training data was full of them.
How to spot it: npm install log shows “deprecated” warnings. package.json newly includes a known-stale dep.
Shortest path to fix
Step 1: AGENTS.md “modern only” rule
## API and framework rules
Target stack: React 18, TypeScript 5, Node 20, Python 3.12.
Do not use, in new or modified code:
- React class components — use function components and hooks
- `React.FC` / `React.FunctionComponent` — type props directly
- `componentWillMount`, `componentWillReceiveProps`, `componentWillUpdate`
- jQuery, Backbone, or any code patterns from before 2020
- `var` — use `const` / `let`
- `require()` in TypeScript/ESM files — use `import`
- Promise-returning callbacks inside `useEffect`
- npm: `request`, `moment`, `node-fetch@2`, `uuid@3` — see "approved packages"
- Python: `print` statement, `urllib2`, `from __future__`, type comments
When in doubt about a pattern's current status, search the package's
GitHub README for "deprecated" before using it.
The agent now has a hard list to check against, not vibes.
Step 2: Install eslint-plugin-deprecation and React-specific rules
npm install --save-dev eslint-plugin-deprecation @typescript-eslint/eslint-plugin eslint-plugin-react
In .eslintrc.js:
module.exports = {
plugins: ['deprecation', 'react', '@typescript-eslint'],
rules: {
'deprecation/deprecation': 'error',
'react/no-deprecated': 'error',
'react/prefer-stateless-function': 'warn',
'@typescript-eslint/ban-types': ['error', {
types: {
'React.FC': {
message: 'Type props directly, do not use React.FC',
fixWith: 'function-component'
}
}
}],
'no-restricted-imports': ['error', {
paths: [
{ name: 'request', message: 'Use the built-in fetch.' },
{ name: 'moment', message: 'Use date-fns or Temporal.' },
{ name: 'node-fetch', message: 'Use the global fetch in Node 18+.' }
]
}]
}
}
Now Codex’s deprecated patterns fail lint. The agent reads lint output and self-corrects.
Step 3: Point the agent at current docs
Add a “docs” section to AGENTS.md:
## Reference docs (use these, ignore older tutorials)
- React: https://react.dev/ (NOT legacy.reactjs.org)
- Next.js: https://nextjs.org/docs (App Router, server components)
- Node: https://nodejs.org/docs/latest-v20.x/api/
- TypeScript: https://www.typescriptlang.org/docs/handbook/
- Python: https://docs.python.org/3.12/
If you cite a pattern, link to one of these. Do not cite blog posts from
before 2023.
The agent will pull patterns from the cited domain rather than its general training data.
Step 4: Audit the codebase for existing deprecated patterns
Old code in the repo gives Codex permission to copy the pattern. Sweep:
# React
grep -rn 'React\.FC\|componentWillMount\|componentWillReceiveProps' src/
# Node
grep -rn "require\('request')\|from 'moment'" src/ package.json
# TypeScript
grep -rn ': any\b\|@ts-ignore' src/
Migrate the existing usages. The agent stops introducing patterns it no longer sees in the repo.
Step 5: Add a CI step running the deprecation scan
# .github/workflows/deprecation-check.yml
name: Deprecation check
on: [pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npm run lint
- name: Custom deprecation scan
run: |
if grep -rn -E 'React\.FC|componentWillMount|require\(.request.\)' src/; then
echo "Deprecated patterns found"
exit 1
fi
Required-status-check this and Codex cannot land deprecated code.
Step 6: Run npm outdated and update dependencies regularly
Old dependencies pull old type definitions. Stale @types/react may still declare React.FC. Refresh quarterly:
npm outdated
npx npm-check-updates -u
npm install
npm test
A modern @types/react will steer Codex toward modern patterns even without other rules.
Prevention
- AGENTS.md lists the deprecated patterns and modern replacements explicitly
eslint-plugin-deprecationandreact/no-deprecatedconfigured as errors- Reference docs section in AGENTS.md points to current canonical sources
- Audit the existing codebase so the agent does not “match” old patterns
- CI runs both lint and a grep-based deprecation scan as required checks
- Keep dependencies fresh;
npm outdatedquarterly, especially@types/*