Why a Small Transformer Can't Copy a Word It Hasn't Seen A developer's small transformer that generates web apps from one-line specs fails to generalize to unseen domains, scoring 0% on held-out feature combinations despite fixing data pipeline issues. The model, trained on 4,176 programs, compiles and serves HTTP for seen domains but cannot copy a word it hasn't seen, instead reusing table names from training data. The retraction reveals that the initial claim about amortizing human labor was wrong, and the failure is due to the model's inability to handle out-of-vocabulary tokens. I have a small transformer that turns a one-line spec into a working web app. It is 11.9M parameters, 6 layers, d=384, trained on 4,176 generated programs. Given "a support ticket system with marking a ticket closed, a stats page, searching tickets and creating and viewing tickets" it writes a 1,158-token Python file that compiles, serves HTTP, implements search, stats and toggle, and does not implement comments, edit, delete or category. On held-out feature combinations it does that 5 times out of 6. Ask it for a book catalogue and it writes an appointment booker. I built this arm to justify a specific claim, and the claim turned out to be wrong. This post is that retraction, plus the three experiments it took to find out why the model fails, one of which corrected a diagnosis I had already written down and believed. I have written about this project once before, on how its verification sweep reports on itself https://sethwheeler.dev/blog/appgen-verification-gap/ . That post is about the symbolic half of the same system; this one is about the learned half and does not depend on it. The code is in a private research repo, so there is no link. Every figure below comes from a results file or a command I ran, and I say which. The shipped tool does not use the model at all. It uses compositional synthesis: a parser turns your request into an entity schema plus a feature set, and hand-written emitters assemble exactly that program. It is exact within its grammar and about 2 ms on a CPU. Its cost is human labour. Each program kind is 160 to 287 lines of hand-written emitter, each language is another 104 to 231, and there is no transfer between them. I wrote in two separate experiment write-ups that this is "precisely the labour a learned generator would amortise." A model, the argument went, would learn the mapping once and cover new cases for free. For a long time that was untestable, because the model scored 0%. Five experiments in a row scored 0/6 compile . The diagnosis I kept reaching for was capacity or training time, and it was wrong every time. Training to 3.5× lower loss left the failure distribution identical. What actually fixed it was two one-line changes to the data pipeline: