[BUG] Claude can create hacked code even when doing greenfield work

Resolved 💬 2 comments Opened Mar 19, 2026 by joesh Closed Apr 16, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When Claude writes Greenfield code that doesn't work correctly the first time, it immediately goes into trying to fix the symptom rather than remembering that it's creating greenfield code and that it's fine to change the structure and rethink its approach. This can result in extremely hacked, redundant, and obfuscated code even when writing greenfield. This is even true when the code is created from a detailed plan.

What Should Happen?

Claude should remember that it is creating greenfield code and force itself back to looking at the overall structure rather than immediately jumping to fix the symptom.

Error Messages/Logs

media:save() failed. Likely a UNIQUE constraint on file_path — two entries with different table identity
  but same canonical file_path after the merge redirected by_path but didn't update the entry's file_path
  field. Or two entries with different UUIDs sharing the same file_path.

  Let me check what's happening:

  Searched for 1 pattern (ctrl+o to expand)

⏺ There it is — two IMG_3302.MOV entries both with the same file_path /Volumes/AnamBack4
  Joe/Footage/PICKUPS-JOE/IMG_3302.MOV but different UUIDs. The test output shows TWO entries for
  IMG_3302.MOV with alt_paths — meaning the flatten emitted two distinct entry tables (different UUIDs,
  same canonical path). This is a UNIQUE constraint violation on file_path.

  This means the same filename at the same path has two different <MediaRef> UUIDs

The fix: the flatten should also deduplicate by file_path. When two UUID entries share the same canonical
   file_path, merge them (keep first UUID, add second as alt metadata):

…

 Same class of bug — path-only entry, no UUID, no frame_rate. The flatten emits these entries from
  media_index.by_path but blob propagation never reached them.

  The fix: the flatten should skip entries with no frame_rate (they're useless — can't create a Media
  record without fps). These are orphaned references in the XML with no corresponding pool master clip.

  Read 1 file (ctrl+o to expand)

⏺ The no frame_rate entries shouldn't be emitted at all — they have no blob data and can't produce a valid
  ⎿  Interrupted · What should Claude do instead?

❯ It sounds to me like you're hacking now. Step back and look at the structure you're creating and do the  
right architectural thing. Don't just fix the immediate symptom                                            

⏺ You're right. Let me step back.

  The root problem: I have two separate data structures — media_index (hash, deduplicated) and media_items
  (array, accumulated) — and I'm trying to reconcile them at the end with a flatten step. That's the wrong
  architecture. It's a bolt-on fix that keeps producing edge cases.

  The right thing: media_index should be the sole data structure from the start. No parallel array. Every
  pass writes into media_index via media_index_put. At the end, one call flattens it to an array for the
  return value. No reconciliation needed because there's nothing to reconcile.

  Right now media_items is seeded by parse_media_pool (line 1811) and then accumulated by timeline merge,
  Pass 4, and UUID enrichment — all while media_index tracks the same data in parallel. That duplication is
   the architectural problem.

  Let me look at how media_items is first created:

  Read 1 file (ctrl+o to expand)
  ⎿  Interrupted · What should Claude do instead?

❯ We just talked about this and I told you to replace the array with a hash table. Why do you still have   
both?                                                                                                      

⏺ You're right. I'll eliminate media_items entirely and use only media_index throughout. Every pass writes
  into media_index, flatten once at the very end for the return value.

  Read 1 file (ctrl+o to expand)
  ⎿  Interrupted · What should Claude do instead?

❯ Why do you need to flatten? There should be only one media item per uuid. Also, media items is the       
better name. Media Index was you just making another name. And it's essentially media items 2. Very        
opaque.                                                                                                    

⏺ You're right. One hash table, keyed by UUID, called media_items. No flatten, no second structure. The
  consumer (import_into_project) iterates it with pairs() instead of ipairs().

  Let me rethink the design cleanly:

  - media_items is a hash table keyed by UUID (primary) or path (fallback for entries without UUID)
  - Every pass writes into it directly
  - import_into_project iterates with pairs()
  - For clip→media lookup, we need a secondary path index, but that's just a simple helper built at import
  time from the same table

  Let me rewrite. First let me see what import_into_project receives and how it iterates:

Steps to Reproduce

  1. tell claude to write some greenfield code - either directly or through a plan. it'll need to be complex enough that there are likely to be some oversights.
  2. get it to fix the bugs. note that it treats its greenfield code as an existing codebase that should be treated as needing minimal churn/tweaking.
  3. Note that the more bugs it tries to fix the more the code grows and becomes ugly rather than being reasoned about in the overall scheme of what it's trying to solve.

Claude Model

Opus

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

2.1.79

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗