Context-Blind Naming.
An AI assistant names new code with generic placeholders or a fresh convention that ignores the repository's existing identifiers and domain vocabulary, eroding readability and spawning duplicate, mis-described concepts.
##Signs and Symptoms
A reviewer spots Context-Blind Naming when the names in an AI-authored diff are locally plausible but disconnected from the surrounding repo. Tell-tales:
- Generic placeholders in domain code:
data,result,temp,item,obj,payload,response,value,handleStuff,processDatawhere the module already speaks a specific language (grossPremium,Customer,getCustomerById). - Convention drift: a
snake_casesymbol dropped into acamelCasefile, a missingis/hasboolean prefix, or a new CRUD verb (fetch*) in a codebase that standardized onget*. Each diff "follows whichever style it last encountered, introducing a fourth convention. Then a fifth." - Synonym sprawl / duplicate concepts: the AI invents
fetchUserwhengetCustomerByIdalready exists, or mixescustomer/client/userfor one entity — re-implementing instead of reusing. - Names that describe mechanism, not intent — or lie about behavior:
processData()that actually computes sales tax. Agents (and the next agent) "readprocessData()and proceed as if that name tells the full story," so the wrong meaning propagates to every call site.
// Repo already exports getCustomerById(id: CustomerId): Promise<Customer>
// AI adds a near-duplicate with context-blind names:
async function fetchData(id: string) { // generic verb, loose type
const result = await db.query("select * from customers where id = $1", [id]);
const temp = result.rows[0]; // 'temp' hides that it's a Customer
return temp; // nothing here says "Customer"
}
##Reasons for the Problem
Why models produce it
- Next-token frequency bias. Across the training corpus,
data/result/temp/fooare the highest-probability identifiers, especially in the tutorial and boilerplate code LLMs ingest heavily. Generating the statistically average name is exactly what a next-token predictor is optimized to do, which smooths domain intent away (Towards Data Science). - No (or truncated) repo context. The model rarely sees the sibling module's glossary or the existing
getCustomerById. GitClear ties the duplication surge directly to this: the assistant "is less likely to propose reusing a similar function elsewhere... partly because of limited context size" (GitClear 2025). - Local optimization / weak refactoring instinct. Each turn optimizes the immediate prompt, "without considering cumulative architectural impact." OX Security found Avoidance of Refactors in 80–90% of AI code, so the model adds a freshly named symbol rather than rename or reuse an existing one (OX report).
- Training-cutoff staleness. Conventions and API names from older corpora resurface even after a project has moved on.
Why it hurts
- Readability/maintainability: names are a codebase's primary documentation; generic ones force every reader to re-derive intent from the body.
- Duplication and defects: renaming a concept spawns a parallel implementation. GitClear measured an ~8x rise in duplicated blocks and copy/paste overtaking moved (refactored) lines for the first time in 2024; clones carry an estimated 15–50% more defects.
- Agent feedback loop (the AI-specific harm): names are the interface the next agent reads at face value. A misleading or generic name "propagates errors through all agent-generated code that builds upon it" (AI Pattern Book).
- Review load & correctness: reviewers must mentally map
temp/databack to domain concepts, which hides bugs; misleading names cause wrong usage at call sites. - Security/audit blind spots: a secret or token parked in a var named
data/tmpslips past name-based greps and review attention.
Note: research like arXiv 2509.20491 shows static tools catch local, explicit smells well, but the domain-meaning facet here is value/intent-dependent and largely escapes automated detection.
##Treatment
Review & prompting tactics
- Feed the conventions and glossary into context. Keep a short naming guide (casing, boolean prefixes, CRUD verbs, domain terms) in
CLAUDE.md/style docs and require the model to follow it. Apply domain-glossary terms consistently so synonyms collapse to one word. - Force reuse before creation. Prompt: "Search the repo for an existing function/type for this before adding one; reuse it." This directly counters the duplicate-concept failure GitClear and OX flag.
- Name things in the prompt. "Name the handler
createRefund" beats "add refund processing." Specify domain names (monthlyRevenue, notfloat1). - Require the linter + duplication scan to run on the diff (naming-convention +
id-denylist+ jscpd) and have the model fix violations rather than you doing it by hand.
The refactor — apply Rename Variable/Function (Fowler's "Change Function Declaration"), fixing the Mysterious Name smell, and Consolidate Duplicate Code by reusing the existing symbol instead of the new one.
Before:
async function fetchData(id: string) {
const result = await db.query("select * from customers where id = $1", [id]);
const temp = result.rows[0];
return temp;
}
After (reuse the existing repository fn; intention-revealing, convention-matching names and types):
// Don't re-query — reuse getCustomerById and keep the domain vocabulary.
async function getCustomerById(id: CustomerId): Promise<Customer | null> {
const { rows } = await db.query<Customer>(
"select * from customers where id = $1",
[id],
);
return rows[0] ?? null;
}
If a misleading name already shipped, rename it to match behavior (processData → calculateSalesTax) before building on it, so downstream agents and humans inherit the correct signal.
##Detected by
- ESLint (core) id-denylist — Disallow specified identifiers
- ESLint (core) id-length — Enforce minimum/maximum identifier length
- typescript-eslint @typescript-eslint/naming-convention — Enforce naming conventions (casing/prefixes)
- eslint-plugin-unicorn unicorn/prevent-abbreviations — Prevent abbreviations / overly generic names
- SonarQube / SonarSource typescript:S117 — Local variable and parameter names should comply with a naming convention
- jscpd copy-paste-detection — Detects duplicate blocks created when a renamed concept duplicates an existing one