What it does
Flags consecutive duplicate or near-identical code blocks that should be extracted into a shared function or abstraction.
Why AI tools generate this pattern
AI tools frequently copy-paste logic with slight variations instead of abstracting it. When requirements change, each copy needs to be updated independently — and they often aren't, leading to subtle inconsistencies between similar code paths.
Code Examples
✕ Incorrect (Flagged by AI Guard)
// Same validation logic duplicated across two routes
router.post('/create-user', async (req, res) => {
if (!req.body.email || !req.body.email.includes('@')) {
return res.status(400).json({ error: 'Invalid email' });
}
if (!req.body.password || req.body.password.length < 8) {
return res.status(400).json({ error: 'Password too short' });
}
// create user...
});
router.put('/update-user/:id', async (req, res) => {
if (!req.body.email || !req.body.email.includes('@')) {
return res.status(400).json({ error: 'Invalid email' });
}
if (!req.body.password || req.body.password.length < 8) {
return res.status(400).json({ error: 'Password too short' });
}
// update user...
});✓ Correct (Safe & Deterministic)
// Extract into a shared validation function
function validateUserInput(body: unknown): string | null {
if (!isObject(body)) return 'Request body required';
if (!body.email?.includes('@')) return 'Invalid email';
if (!body.password || body.password.length < 8) return 'Password too short';
return null;
}
router.post('/create-user', async (req, res) => {
const error = validateUserInput(req.body);
if (error) return res.status(400).json({ error });
// create user...
});
router.put('/update-user/:id', async (req, res) => {
const error = validateUserInput(req.body);
if (error) return res.status(400).json({ error });
// update user...
});How to Fix
- Extract the duplicated logic into a named function, middleware, or utility module and call it from each location.
Nuances & False Positive Prevention
Legitimate usage can be exempted with inline disable comments (// ai-guard-disable-next-line no-duplicate-logic-block) when appropriate.
Configuration
Enable or override this rule in your ESLint configuration:
eslint.config.mjs
// eslint.config.mjs
export default [
{
plugins: { 'ai-guard': aiGuard },
rules: {
'ai-guard/no-duplicate-logic-block': 'warn',
},
},
];