ilo: A Programming Language for AI Agents, Not Humans

Error Output Is an Agent Interface

While reviewing ilo this month I measured something embarrassing: feeding a malformed 165KB file to ilo check produced an error message around 42,000 tokens long. For a human that is an annoyance to scroll past. For an agent it is a catastrophe, because the error message is the input to the retry. This post covers:

  • Where the bloat comes from, 233 debug-print sites
  • Why error size compounds differently for agent authors
  • What the fix looks like, and the prior art ilo already has

Anatomy of a 42k-token error

The audit found 233 places in the ilo codebase that format errors with Rust’s {:?} debug representation, which prints entire values. When the value is a parse tree or a large input fragment, the “message” becomes a dump of everything the compiler was holding. The 165KB input produced an error transcript larger than many models’ working headroom for the actual fix.

There were sharper edges in the same review: two malformed inputs that produce native aborts rather than errors at all, a prefix chain around 3,500 deep taking down ilo check, and an unguarded parse path. An abort is the worst error message, zero information at any token price.

Agents pay for errors twice

A human reads an error once, with eyes that skip. An agent pays for the error as context, and then pays again because a bloated error displaces the code it was about to fix. In a language that markets itself on token cost, a 42k-token error wipes out the savings of dozens of programs. The write-side economics that justify terse syntax apply with more force to the read side, because errors arrive precisely when the loop is already running: generate, check, read error, regenerate.

ilo already has the counter-example in its own toolchain. The verifier reports all errors at once with hints, a design chosen because batched errors with suggestions are cheaper than agents discovering problems one execution at a time. That principle, written down for the verifier, was never applied to the rest of the error output.

The fix is a budget

The same discipline I argued for with spec size applies: give error output a token budget. Concretely, for ilo:

  • Replace value dumps with typed summaries: kind, location, one-line excerpt with a caret, expected-versus-found
  • Cap any embedded input excerpt at a fixed line count
  • Turn the two aborting paths into ordinary bounded errors first, since no formatting fixes an abort
  • Keep the all-errors-at-once batching; it is the part already right

An error message for an agent should be the shortest string that makes the next generation correct. Measured that way, most compiler errors, ilo’s included, carry an order of magnitude of waste.