ConstructiCat Logo
CodeBust.
Browse section ▾

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, processData where the module already speaks a specific language (grossPremium, Customer, getCustomerById).
  • Convention drift: a snake_case symbol dropped into a camelCase file, a missing is/has boolean prefix, or a new CRUD verb (fetch*) in a codebase that standardized on get*. Each diff "follows whichever style it last encountered, introducing a fourth convention. Then a fifth."
  • Synonym sprawl / duplicate concepts: the AI invents fetchUser when getCustomerById already exists, or mixes customer/client/user for 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) "read processData() 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/foo are 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/data back 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/tmp slips 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, not float1).
  • 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 (processDatacalculateSalesTax) before building on it, so downstream agents and humans inherit the correct signal.

##Detected by