Bassam Ismail
What a Genuinely Blocked AI Agent Should Report
Agent operating noteJuly 11, 2026
Field note / operating model / team artifact

What a Genuinely Blocked AI Agent Should Report

A practical field note from real Claude, Codex, and coding-agent work: the incident, engineering decision, reusable artifact, and limits.

Format
Field note + team artifact
Reading time
4 min
Primary use
Agent operating practice

"Blocked" should be a technical state, not a mood and not a synonym for "I tried several things." A useful blocker report proves that progress stopped on a specific dependency, preserves completed work, and names the smallest change that would make a new attempt materially different.

Without that contract, agents tend to loop, delegate into the same restriction, or replace missing evidence with a polished inference.

Agent context
ClaudeCodexReviewer
Pattern
Dependency-aware blocker report
Output
Unblocking packet
Use when
Retries share the same failed capability, external state, permission, or unavailable evidence source

Ten commands were one attempt

In one research session, the task required read-only Git history. The execution harness denied shell access. Ten commands failed with the same permission error, and a delegated agent inherited the restriction.

Counting those as ten independent attempts would suggest persistence. Operationally, they were one attempt repeated against an unchanged dependency: shell capability unavailable in this execution context.

The useful result was the report produced after the retries stopped. It stated what had been established from readable files, which commit-level claim remained unproved, and the exact read capability needed to continue.

Fingerprint the dependency, not the wording

Error messages vary. The blocker identity should be based on the dependency and operation:

blocker_fingerprint =
  capability:shell.read
  + resource:repository-history
  + operation:git-log
  + execution_context:session-42

Retry only when at least one part of that fingerprint changes or when the failure is explicitly transient. Changing the command syntax, asking another model in the same harness, or restating the objective does not create a new attempt.

This rule prevents retry theatre and gives orchestration code a deterministic stop condition.

Return an unblocking packet

OBJECTIVE
The claim or outcome the task was meant to establish.
 
COMPLETED
Facts established, artifacts produced, and evidence locations.
 
BLOCKER
Failed dependency, operation, exact error category, and blocker fingerprint.
 
ATTEMPTS
Distinct approaches tried. Group retries that shared the same dependency.
 
IMPACT
The claims that cannot be made without the missing evidence.
 
UNBLOCK
The smallest capability, input, state change, or scope decision required.
 
SAFE NEXT ACTION
An exact read-only or reversible step for the next operator.

Applied to the repository incident:

OBJECTIVE
Identify the commit that introduced the behavior and show the exact diff.
 
COMPLETED
Located the current implementation and the regression test that describes the behavior.
 
BLOCKER
Git history is unavailable because this session lacks shell.read.
Fingerprint: shell.read + repository-history + git-log + current-session.
 
IMPACT
The current code can be described, but authorship, introduction date, and causal commit are unproved.
 
UNBLOCK
Grant read-only Git commands in this repository, or provide an approved history export.
 
SAFE NEXT ACTION
Run `git log -S'<relevant token>' -- src/path/to/file.ts`, then inspect the candidate diff.

The report does not ask the reviewer to reconstruct the session. It preserves the useful work and makes the next decision small.

Blocked is different from incomplete

An agent is incomplete when work remains but a valid next action is available inside the current authority and evidence set. It is blocked when every safe next action depends on a missing capability, external state change, human decision, or unavailable source.

That distinction matters for orchestration. Incomplete work should continue. Blocked work should return control. A timeout alone establishes neither.

I would use these stop rules:

ConditionStateResponse
A different evidence source remains availableIncompleteTry the bounded alternative
The same dependency fails repeatedlyBlockedStop and emit the packet
A transient dependency has a documented retry policyWaitingRetry within the budget, then block
Scope can be narrowed without misrepresenting the resultDecision neededOffer the narrower claim explicitly
The remaining gap does not affect acceptance criteriaComplete with caveatReport the caveat and finish

The sharp edge is premature surrender

A blocker contract can make agents stop too early. The first failed tool call may have a cheap alternative, and over-constrained agents can turn ordinary debugging into a queue of permission requests.

Require at least one materially different safe approach when one exists. The alternative must change the evidence source, dependency, or method, not merely the phrasing. Also distinguish permission denial from a malformed command and an unavailable service from a wrong endpoint.

The reviewer has a responsibility too. If the same blocker packet appears across sessions, fix the harness, connector, documentation, or task design. Repeatedly granting one-off exceptions leaves the underlying operating defect intact.

The best blocker report is not an apology. It is a compact transfer of control that lets the next operator change the one condition that made every previous retry equivalent.

More to read