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.
Safety in the wrapper, not the binary
Section titled “Safety in the wrapper, not the binary”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).
No mutation gate at all
Section titled “No mutation gate at all”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).
Unbounded output
Section titled “Unbounded output”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).
Device/API errors returned as success
Section titled “Device/API errors returned as success”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).
Secrets on the command line
Section titled “Secrets on the command line”Accepting --password … / --token … as arguments, leaking them to ps, /proc, and shell
history. Fix: stdin / env / keyring only (Auth).
Human-only help, machine-blind tool
Section titled “Human-only help, machine-blind tool”No --json, no schema, no machine-readable surface — the agent must scrape prose. Fix:
structured output + self-description (I3,
I6).
Unstable / renamed output fields
Section titled “Unstable / renamed output fields”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).
Unfenced untrusted content
Section titled “Unfenced untrusted content”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).
Mirroring the API instead of the task
Section titled “Mirroring the API instead of the task”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.