Path-alias hallucinations are one of the most common AI failure modes: the model writes import { calculateTax } from '@/lib/billing/calculator' for a file it imagined rather than a file that exists. The TypeScript compiler and the bundler both fail at the resolution step, so the build breaks and the route cannot render. Even when tsc --noEmit is skipped in CI, runtime imports via dynamic import() throw Cannot find module the first time the code path executes in production.
High because an unresolved alias breaks the build or crashes the route at runtime, though a passing `tsc` step catches it before deploy.
Run tsc --noEmit to surface every unresolved alias, then for each one decide whether to create the missing file or correct the import specifier. Fix the reference in place:
// Correct: points at a file that actually exists under src/lib/billing/
import { calculateTax } from '@/lib/billing/tax'
If the alias itself is wrong, update tsconfig.json compilerOptions.paths so the prefix maps to the real directory.
ID: ai-slop-hallucinations.module-references.path-aliases-resolve
Severity: high
What to look for: Read tsconfig.json and any tsconfig.*.json files. Extract compilerOptions.paths to build the alias map (e.g., "@/*": ["./src/*"]). For every import in source files whose specifier matches an alias prefix, resolve the alias to the target directory and verify the resolved path points to an actual file. Apply standard extension resolution: try .ts, .tsx, .js, .jsx, .mjs, .cjs, then try index.ts, index.tsx, index.js, index.jsx if the resolved path is a directory. Count all alias imports inspected, total resolved, total unresolved.
Detector snippet (Node-capable tools only): If the tool has a shell with Node available, parse tsconfig.json paths, scan every source file for imports matching an alias prefix, and resolve each target against the filesystem. Output reports the total alias imports and the count + identity of the unresolved ones. If exit 0 with "unresolved=0", report pass. If "unresolved>0", report fail with count. Exit >=2 or command not found — fall back to prose reasoning below.
node -e 'const fs=require("fs"),path=require("path");const ts=JSON.parse(fs.readFileSync("tsconfig.json","utf-8"));const paths=(ts.compilerOptions&&ts.compilerOptions.paths)||{};const base=(ts.compilerOptions&&ts.compilerOptions.baseUrl)||".";function w(d,o=[]){try{for(const e of fs.readdirSync(d,{withFileTypes:true})){if(e.name==="node_modules"||e.name===".next")continue;const p=path.join(d,e.name);e.isDirectory()?w(p,o):o.push(p)}}catch{}return o}let t=0,u=[];for(const f of w("src")){if(!/\.(ts|tsx|js|jsx|mjs)$/.test(f))continue;const s=fs.readFileSync(f,"utf-8"),imp=[...s.matchAll(/from\s+[\u0022\u0027]([^\u0022\u0027]+)[\u0022\u0027]/g)].map(m=>m[1]);for(const i of imp){for(const [k,vs] of Object.entries(paths)){const pre=k.replace(/\*$/,"");if(!i.startsWith(pre))continue;t++;const rest=i.slice(pre.length);let ok=false;for(const v of vs){const rp=path.resolve(base,v.replace(/\*$/,rest));for(const ext of ["",".ts",".tsx",".js",".jsx","/index.ts","/index.tsx"]){if(fs.existsSync(rp+ext)){ok=true;break}}if(ok)break}if(!ok)u.push(f+": "+i);break}}}console.log("total="+t+" unresolved="+u.length);u.slice(0,3).forEach(x=>console.log(x))'
Pass criteria: 100% of alias-prefixed imports resolve to an existing file (with extension) or directory containing an index file. Report: "X alias imports inspected, Y resolved, 0 unresolved."
Fail criteria: At least 1 alias-prefixed import resolves to a non-existent path after extension resolution.
Do NOT pass when: The alias map is empty but imports use alias-style paths (@/lib/foo with no @/* alias defined) — those should be flagged as unresolved.
Skip (N/A) when: tsconfig.json does not exist OR tsconfig.json does not define compilerOptions.paths.
Report even on pass: Always report the count. Example: "147 alias imports inspected (alias prefixes: '@/', '~/'), 147 resolved (100%)."
Detail on fail: "5 alias imports do not resolve: '@/lib/billing/calculator' in src/app/checkout/page.tsx, '@/components/MissingDialog' in src/app/page.tsx (file not found in src/components/)"
Remediation: Path alias hallucinations are a top AI failure mode — the model imagines a @/lib/utils helper that doesn't exist. Fix each unresolved alias import:
// Bad: AI imagined this file
import { calculateTax } from '@/lib/billing/calculator'
// Good: import from a file that actually exists, or create the file
import { calculateTax } from '@/lib/billing/tax'
Run tsc --noEmit to surface module-resolution errors at build time. If a file should exist, create it. If the import was wrong, fix the path. If the alias is misconfigured, update tsconfig.json compilerOptions.paths.