Make invalid states unrepresentable (for your agents)

andy_xor_andrew1 pts0 comments

Make invalid states unrepresentable (for your agents) | ⌨️🤷🏻‍♂️📷<br>Make invalid states unrepresentable (for your agents)<br>July 6, 2026This blog post was written by me, a human (as evidenced by how long it takes to explain a simple idea). If you want to skip straight to the main idea, scroll to The Point.<br>There is an old saying: make invalid states unrepresentable .<br>Like all maxims in computer science, one could debate its usefulness. Maybe you read it and think: Yes! Exactly! Or maybe you read it and recall a time as a junior dev, when a senior dev ruined your Friday by commenting on your PR with these four words.<br>Regardless, as a guiding principle, it is certainly useful. Entire classes of bugs can be eliminated from programs, just by designing your solution in a way that certain failure states are not merely edge cases but logically impossible.<br>Lately I have noticed that this approach is very effective when applied to agents , massively increasing their reliability for many tasks. I will detail the pattern below.<br>First, some old-school code examples. Feel free to skip them if you already get the gist.<br>Some (contrived) examples<br>Ways you might &ldquo;make invalid states unrepresentable&rdquo;:<br>In some programming languages, null reference exceptions are made impossible by treating nullable references as entirely different types from non-nullable references.

If a purchase order can only be &ldquo;accepted&rdquo;, &ldquo;rejected&rdquo;, or &ldquo;pending&rdquo;, you can represent this with a closed enum instead of a string (so it is not &ldquo;stringly typed&rdquo;), and it becomes impossible for callers to provide an invalid value.

Say you have a USERS table, and all users are required to have email addresses. But, some user accounts are pre-created by their employer, before the email address is known. In such cases, users provide the email address upon first sign-in. Instead of allowing the email field to be nullable, you can have an entirely separate table PENDING_USERS which allows null emails, and only create the real USERS entry once the email is known upon first sign-in. You just eliminated the possibility that a USER may be missing an email address; such a state is unrepresentable, since email is NOT NULL on USERS.

Maybe those examples are obvious, boring, even common sense. So let&rsquo;s move on to agents.<br>&ldquo;Make no mistakes&rdquo;<br>I&rsquo;d say there are two general approaches when designing LLM-powered solutions:<br>The code drives the LLM.<br>The LLM drives the code.<br>The former was common in prehistoric times (~2023). Think: langchain, semantic kernel, old-school OpenAI SDK. In this approach, you write &ldquo;traditional&rdquo; code, which calls into LLMs when it&rsquo;s time to make a decision. You control the loop, you control the&mldr; well, the control flow. Your code drives the LLM.<br>The latter is becoming the norm, now that everything is &ldquo;agentic&rdquo;. Think: Claude Code, OpenClaw, the latest harness-du-jour, etc. In this approach, the LLM operates in a harness (as an &ldquo;agent&rdquo;) with lots of tools at its disposal. You may provide it with code it can run; whether it actually invokes the code is up to the agent. The agent has free rein, and you let it loose on a task. The agent owns the loop, decides what to do, decides when to stop. There isn&rsquo;t strictly a &ldquo;program&rdquo; being executed; at each step, the next step is decided on the fly by the agent. The LLM drives your code, invokes your tools&mldr; if it chooses.<br>Apologies for the Agents 101. My audience surely is familiar with these concepts. But I wanted to outline it explicitly, to set up this thought experiment:<br>Say you wanted to auto-generate a technical wiki for any given codebase. Basically, implement DeepWiki. How would you do this?<br>Well, first let&rsquo;s define what a &ldquo;wiki&rdquo; is. For our purposes, an example &ldquo;wiki&rdquo; created by our system might be a folder that looks like this:<br>wiki/<br>OVERVIEW.md<br>control-plane/<br>OVERVIEW.md<br>running-locally.md<br>system-architecture.md<br>plugin-system.md<br>user-management-service/<br>OVERVIEW.md<br>account-creation-flow.md<br>...<br>service-lifecycle/<br>...<br>There&rsquo;s always a top-level OVERVIEW.md page which is a landing page for the entire wiki.<br>There are &ldquo;sections&rdquo; which are folders that group relevant wiki pages by logical systems or concepts (e.g. user-management-service/)<br>Each &ldquo;section&rdquo; also has an OVERVIEW.md which is the landing page for that section.<br>Each &ldquo;section&rdquo; has &ldquo;pages&rdquo; which are the markdown files that contain the wiki content.<br>On top of that, let&rsquo;s say wiki generation is configurable . A config file for our wiki-generator system might look like this:<br># wiki-config.yaml<br>max_sections: 12<br>max_pages_per_section: 3

# These sections are always generated, forcefully:<br>default_sections:<br>- name: Application Lifecycle<br>description: Explains the startup, shutdown, and deployment process

Basically, we may...

ldquo rdquo wiki code make email

Related Articles