Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Cargo Cult Programming

Antipattern

A recurring trap that causes harm — learn to recognize and escape it.

“The form is perfect. But it doesn’t work.” — Richard Feynman, “Cargo Cult Science”

Copying the visible shape of working software without understanding the invariant that made the original work.

Understand This First

  • AI Smell — surface signs that model output was optimized for plausibility rather than understanding.
  • YAGNI — the heuristic that rejects features and abstractions you do not need yet.
  • Verification Loop — the feedback cycle that makes copied structure prove itself.

Symptoms

  • The code includes a framework, pattern, dependency, middleware layer, or configuration block because “that’s how examples do it.”
  • Nobody on the team can explain which requirement the copied structure serves.
  • The agent produces a familiar enterprise shape: interfaces with one implementation, factories around simple constructors, retry wrappers around non-idempotent calls, or dependency injection where a plain function would do.
  • Review comments get answered with precedent, not reasoning: “This is how the tutorial did it” or “the model generated it that way.”
  • Tests prove the happy path but never exercise the invariant the pattern is supposed to protect.
  • Removing the copied structure doesn’t break anything meaningful, because it never did meaningful work.

Why It Happens

Cargo cult programming starts with a real observation: a piece of software worked somewhere else. The mistake is treating the visible form as the cause. The copied project had a repository abstraction, so the agent adds one. The sample app used a message bus, so the new service gets a message bus. The tutorial wrapped every response in a generic result object, so the production code does too.

The original may have had a reason. The repository isolated a legacy database. The bus decoupled teams with separate release schedules. The result wrapper carried typed error details through a public API. When those forces are absent, the copied shape becomes ritual.

Agents make the trap easier to fall into because they are fluent mimics. A model has seen thousands of codebases where certain pieces co-occur. Ask it for a “production-ready” service and it may reproduce the shape of a mature system before your problem has earned that shape. The result feels professional because it resembles professional code. That feeling is the danger.

The term is also a warning about humility. “Cargo cult” has a complicated anthropological history, and the software use is a metaphor inherited from Feynman and hacker culture. Use it to criticize imitation without understanding, not to sneer at people learning by example. Everyone learns by copying at first. The antipattern begins when copying becomes a substitute for thought.

The Harm

Cargo cult programming adds complexity with no corresponding payoff. The code is harder to read, harder to test, and harder to change, but the extra machinery doesn’t buy isolation, safety, speed, or clarity. It only buys the appearance of sophistication.

The deeper harm is false confidence. A team sees a known pattern name and stops asking whether the pattern fits. A reviewer sees tests and misses that they only test the copied shape. A founder sees an agent produce a folder tree that looks like a real SaaS backend and assumes the architecture is sound.

In agentic coding, the harm compounds across prompts. Once the first ritual layer lands, the agent treats it as local convention. Future changes preserve it, extend it, and build around it. The unnecessary repository gets a factory. The factory gets an interface. The interface gets a mock. The mock gets brittle tests. A small program becomes a museum of patterns nobody chose.

The Way Out

Ask what job each structure performs in this codebase. Not what job it performs in general. Not what job it performed in the example. In this codebase, for this requirement, under these constraints, what would break if you removed it?

Use three checks:

Name the force. Every pattern balances forces. If you cannot name the force, you probably do not need the pattern. “We need a repository” is not a force. “We need to keep domain logic independent of a database we are replacing next quarter” is.

Run the deletion test. Ask the agent to remove the copied structure in a branch and simplify the code. Run the tests. Read the diff. If the simpler version keeps the behavior and improves Local Reasoning, the copied structure was not doing enough work.

Verify the invariant. If the structure remains, write the test that proves why it remains. A retry wrapper needs an idempotency test. A sandbox needs an escape test. A boundary needs a dependency-direction test. A pattern that cannot be tested may still be useful, but the burden of explanation goes up.

Tip

When an agent adds a pattern you did not request, ask it to justify the pattern in one paragraph and propose the simpler alternative. Then make it compare the two against the actual requirement. If the justification is generic, delete the pattern.

How It Plays Out

A developer asks an agent to build a small internal webhook receiver. The agent creates controllers, services, repositories, interfaces, factories, DTO mappers, and a message queue. It looks like a serious backend. The actual requirement is one endpoint that verifies a signature, writes a row, and returns 200. During review, nobody can explain what the repository protects or why the queue exists. The team deletes most of the structure, keeps the signature verification and persistence logic, and ends up with code they can reason about.

Another team asks an agent to add retries around outbound API calls. The agent copies a standard exponential-backoff wrapper from a common pattern. The code retries POST requests that create invoices. The tests pass because the fake API returns a transient 500 and then a 200. In production, the partner API accepts the first request but times out before responding, then accepts the retry as a second invoice. The wrapper looked like resilience. Without idempotency, it was duplicate billing.

A founder prompts for “clean architecture” because a blog post said it scales. The agent produces ports, adapters, use cases, presenters, and dependency inversion. Six weeks later, the product has three screens and one SQLite database, but every feature needs edits in seven files. The founder did not get clean architecture. She got a ritual copy of its nouns.

Sources

  • Richard Feynman’s Cargo Cult Science (Caltech, 1974) supplied the metaphor this software term inherited: the visible form can be perfect while the thing that makes it work is missing.
  • The Jargon File entry for cargo cult programming records the hacker-culture sense of ritual code whose original bug or reason was never understood.
  • Steve McConnell’s Cargo Cult Software Engineering (IEEE Software, 2000) extended the metaphor from individual code to organizations that copy process or overtime rituals without the competence that made the originals succeed.
  • Tommi Mikkonen and Antero Taivalsaari’s Software Reuse in the Generative AI Era: From Cargo Cult Towards AI Native Software Engineering (arXiv, 2025) connects cargo-cult reuse directly to generative AI, arguing that AI-assisted reuse can amplify trust in code whose rationale the developer has not examined.