Skip to content

Antipatterns

These are real, observed failures from the 2025–2026 wave of agent CLIs. Each maps to an invariant it violates. If you recognize one in your tool, that’s the fix list.

Confirmation/safety implemented only in a wrapper or “skill” layer, while the binary itself will mutate on one command. An agent that shells out directly bypasses the wrapper entirely. Fix: put the read-only gate in the binary (I2).

Destructive/outward actions fire immediately with no opt-in — and, worse, some default to fanning out to every target (e.g. changing settings for an entire household/fleet). Fix: read-only default + explicit gate + per-target scoping (Safety).

A confirmation prompt an agent can’t answer

Section titled “A confirmation prompt an agent can’t answer”

Guarding a mutation with an interactive y/N prompt. An agent has no TTY; off-TTY this either hangs forever or is auto-answered. Fix: a scriptable flag gate + --no-input that hard-fails (I5).

The JSON envelope that swallows your own flags

Section titled “The JSON envelope that swallows your own flags”

Wrapping results in a hand-built envelope emitted directly ({command, data, …}) so that --select / --limit / --format silently stop applying. Fix: route parsed data through the one output writer; bound and project before emitting (Foundations, I8).

Dumping a 10,000-row table (or a full show tech-support) by default, blowing the agent’s context. Fix: default limit + pagination + projection (Token economy).

A failed upstream command whose error text is returned as ordinary stdout with exit 0, so the agent “succeeds” with garbage. Fix: detect the failure signal and raise a structured error with a non-zero code (I7).

Accepting --password … / --token … as arguments, leaking them to ps, /proc, and shell history. Fix: stdin / env / keyring only (Auth).

No --json, no schema, no machine-readable surface — the agent must scrape prose. Fix: structured output + self-description (I3, I6).

Renaming or repurposing a JSON field (or a command/flag) in a minor release, silently breaking every agent script that depended on it. Fix: append-only surface; major-bump breaking changes (I10).

Returning attacker-influenceable free text (messages, logs, descriptions) without marking it, letting injected instructions reach the agent as if trusted. Fix: fence untrusted output by default (I9).

One CLI command per upstream endpoint, forcing the agent to orchestrate many low-level calls and filter the results itself. Fix: few task-shaped commands that return the high-signal result (Token economy).

Safety story that depends on the model behaving

Section titled “Safety story that depends on the model behaving”

Relying on a prompt (“the agent will ask first”) instead of a structural guarantee. Prompts are not security. Fix: make the safe behavior structural — the default, enforced by the binary.