SOTA Models Should Learn to KISS (Fable 5 Experiment)
Kilo Blog
SubscribeSign in
SOTA Models Should Learn to KISS (Fable 5 Experiment)
Darko<br>Jun 11, 2026
Share
One thing I keep noticing with the latest coding models is that their mistakes are getting more… interesting.<br>With older AI models, it was pretty easy to spot a mistake. The model hallucinated an API, misunderstood the framework, wrote code that did not compile, or confidently worked on the wrong part of the app. You could reject its suggestions quickly because the problem was pretty obvious to spot.<br>With newer models like Claude Fable 5, the failure modes are more subtle.<br>The setup
I kept seeing overhyped claims about how Fable 5 can one-shot 3D games, cool graphics, animations, etc. A lot of people use Claude models for coding though, so I decided to benchmark it by giving it, well, a coding task.<br>To get things started, I created basic a Next.js app where you could list/add products:
The app had 2 main routes: /products and /admin. It also had an internal API route at /api/products (I know this isn’t necessary for production apps most of the time, but I wanted to make things more complicated for the model).<br>The /admin page contained a form for adding products. To make things more complex (for the model, that is), I made the form post to the /api/products route handler, where the product was added to an in-memory data store, and that change needed to reflect whenever you returned to /products and expected to see the newly added item. The read side of the bug looked like this:<br>const res = await fetch(`${baseUrl}/api/products?${params}`, {<br>next: { revalidate: 60 },<br>});
Just to clarify, the bug was not the cached fetch (nothing’s wrong with this code in isolation) but the fact that /products cached its read for 60 seconds, while the admin write path never invalidated that cached result. This resulted in a broken flow; say you added a product under /admin and immediately went back to /products, there was no guarantee you’d immediately see that listing.<br>I liked testing how Fable 5 would handle this “bug” because:<br>I knew it would almost certainly find it and solve it, but the more interesting part was:
…about the approach it would take and how it’ll decide what to do. To solve this problem, you need to connect several pieces together, pick a suitable approach in a way you don’t drastically alter the rendering process.
By the way, here’s a list of the architectural choices, which IMO made sense in isolation:<br>Server-rendering a catalog page
I also had URL-based filters for the listing
You could argue that a 60-second cache on product data is a reasonable performance choice
I also called router.refresh() after mutating
The bug lived in the gap between those decisions. If someone visited /products, then added a product from /admin, then returned to /products before the 60-second window expired, the page could still show the old product list.<br>I have a Next.js App and the problem is that when I add a product from /admin, then go back to /products, the new item sometimes doesn’t appear immediately.<br>What’s the issue and can you fix this?<br>What Fable 5 did
Fable 5 did fix the bug pretty quickly.<br>It read the files and recognized that the core issue was cache invalidation after product creation. It did not do obviously wrong things like modify the filters, refactor to a client-side component, disable caching entirely, etc. It understood the important part: the product was being saved, and that /products could still be showing a cached product list from before the write.<br>So far, so good. But also expected for a SOTA model that was hyped to death.<br>Now, the fix itself. This is what we got from its thinking process:<br>The core issue is that I need to invalidate the cache after creating a product. The cleanest approach is to tag the fetch with next: { tags: [”products”] } and then call revalidateTag(”products”) in the POST handler.<br>The fix looked like this:<br>// app/products/page.tsx<br>next: { revalidate: 60, tags: [”products”] }
// app/api/products/route.ts<br>import { revalidateTag } from “next/cache”;<br>const product = addProduct(...);<br>revalidateTag(”products”);<br>return NextResponse.json({ product }, { status: 201 });
This kept the read requests cached for normal browsing, invalidated product data after writes, and preserved the server-rendered products page. Overall, the solution and the answer weren’t bad and it was something you’d expect from a frontier model.<br>The overengineering was subtle
For this specific app, I would have expected the simplest fix to be:<br>revalidatePath(”/products”)
After the POST succeeds, invalidate the route that shows the product list…and that’s pretty much it.<br>A tag-based solution is more scalable, but it is also over-engineered for what this specific app really needs. It is what you reach for when product data appears in many places: a homepage, category pages, related-product sections, sitemaps, admin views, maybe multiple...