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 among the most common 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. - No (or truncated) repo context. The model rarely sees the sibling module's glossary or the existing
getCustomerById. DevClass's summary of GitClear's 2025 report notes that assistants are less likely to propose reusing a similar function elsewhere, partly because of limited context size (DevClass on GitClear 2025). - Local optimization / weak refactoring instinct. Each turn optimizes the immediate prompt, not the codebase as a whole. OX Security found Avoidance of Refactors — AI that "excels at generating new code but never goes back to improve architecture" — in 80–90% of the AI-generated code it studied (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's 2025 analysis of 211 million changed lines (2020–2024) found that refactoring-associated ("moved") lines fell from 25% of changed lines in 2021 to under 10% in 2024, while copy/pasted lines rose from 8.3% to 12.3% over the same period; 2024 was the first year copy/pasted lines exceeded moved lines, and code blocks with five or more duplicated lines grew roughly eightfold during 2024 (GitClear 2025).
- Agent feedback loop (the AI-specific harm): names are the interface the next agent reads at face value. As the Encyclopedia of Agentic Coding Patterns puts it, "An AI agent treats the names it finds in a codebase as its primary signal for understanding what things do," and "Inconsistent naming in existing code produces inconsistent naming in generated code" (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: static tools catch local, explicit naming violations well (casing, length, denylisted words), but whether a name matches the domain meaning depends on intent 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 Method (and the same move for variables) to fix misleading names, and remove the Duplicate Code by calling 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 (delete the near-duplicate and call the existing repository function with the domain type):
// Don't re-query — reuse getCustomerById and keep the domain vocabulary.
const customer = await getCustomerById(id as CustomerId);
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 --min-lines / --min-tokens — Detects duplicate blocks created when a renamed concept duplicates an existing one