The single most important rule for an AI agent that answers questions about a production cluster is also the easiest one to violate by accident: never report an all-clear from data you couldn’t fully read. This is the story of a one-line bug that broke that rule, why a green test suite didn’t catch it, and the fix.

The bug

KubeIntellect caps how much of a raw kubectl listing it hands to the model — a real cluster can return tens of thousands of characters of pod output, and an unbounded prompt is both slow and expensive. The code filtered the listing, then cut it to a fixed character cap, in that order:

return True, _filter_snapshot_output(args, out)[:_SNAPSHOT_MAX_CHARS]  # cap = 8000

On a 401-pod cluster — 37,398 characters of listing — with exactly one pod in CrashLoopBackOff, that pod’s row happened to sort past the 8,000-character cut. What the agent received afterward looked completely normal: no error, no truncation marker, nothing to say anything was missing.

Asked “is the cluster healthy,” the coordinator answered from that snapshot: 85 pods reported, no issues, no warnings. Both numbers were wrong. The real pod count was 401, and the cluster was not healthy — the one pod that would have said otherwise had been silently cut away.

A second, quieter failure in the same lines

KubeIntellect also withholds certain namespaces from the model for RBAC reasons, and appends a notice saying so — “N row(s) withheld… this listing is NOT the complete set.” That notice was appended before the character cap, in the same call. On any cluster whose listing exceeded 8,000 characters, the cap could eat the one sentence telling the model — and the user — that rows had been deliberately hidden. The safeguard against reading a short listing as complete was itself getting cut short.

Why a passing test suite didn’t catch it

Every existing test asserted against a flag called ok, which means “the kubectl command itself did not error.” That flag was correctly True the whole time — the command succeeded, the data was just filtered and capped afterward. A related failure mode, a non-zero kubectl exit code, had already been fixed and gated in an earlier release. Fixing half of a defect family made the rest of it look handled — nothing was checking whether a successful command had quietly lost data on the way to the model.

The fix

context_fetcher.py now returns a third value alongside the listing: snapshot_complete. The truncation marker and the withheld-namespace notice are re-appended after the character cap, so they survive it. And the coordinator’s shortcut — answer directly from the cached snapshot rather than re-querying — is gated on that flag, with an explicit instruction never to answer “is the cluster healthy” from an incomplete one. A cluster too large to read in full now gets an honest “I can’t tell you that from what I have,” not a confident, invented number.

Why this is the rule, not an edge case

This was reported against a live cluster by a community contributor, then reproduced independently before the fix and again after. It is worth saying plainly: any real cluster of meaningful size exceeds an 8,000-character pod listing. This was not a rare edge case waiting for an unusually large deployment — it was the default outcome for any cluster past a couple dozen pods, which is most of them.

It is also the exact shape of failure this project treats as disqualifying, not just embarrassing: an AI agent that operates infrastructure has to be more careful about what it doesn’t know than about what it does. A wrong answer that looks confident is worse than a refusal, because a refusal gets checked and a confident wrong answer doesn’t.

Try it, then check it yourself

KubeIntellect is open source. The full fix, with the three related defects found alongside it, is public on GitHub, and you can run the same code path against your own cluster — pip install kubeintellect, then kubeintellect init, which can also create a local Kind cluster to try it on. Or watch the recorded demo first.