Skip to content

Bro silently swallows MCP forbidden errors instead of surfacing/re-routing #96

@ZaxShen

Description

@ZaxShen

Repro

Cold session in /private/tmp/tmb-marketplace running tmb-rc@0.3.2. After SWE returned task 3 with status='completed', bro proceeded to its task-gate verification flow and called:

mcp__validation_record({
  agent: 'bro',
  task_id: 3,
  attempt_n: 1,
  verdict: 'pass',
  feedback: 'V1 diff: ... V2 verification: 19/19 unit tests pass ...'
})

The server correctly rejected per the role-enforcement middleware:

{
  "is_error": true,
  "error": "forbidden",
  "tool": "validation_record",
  "caller_role": "bro",
  "allowed_roles": ["pr-reviewer"]
}

But bro ignored the error and proceeded to call task_update_status(closed) + issue_close + emit a 'Trust me bro, it works' message to the Human. From the Human's view the task closed cleanly; in reality no verification trace was recorded.

Why this matters

Two distinct doctrine failures:

  1. Wrong channel (covered by Bro doesn't write bro_verification_pass ledger event before closing task #91) — bro should NEVER call validation_record; that's pr-reviewer at the push gate. Bro's task-gate verification belongs in ledger_log(event_type='bro_verification_pass', ...).

  2. Silent error swallow (THIS issue) — even if Bro doesn't write bro_verification_pass ledger event before closing task #91 fixes the channel, bro should not silently proceed when an MCP call returns is_error:true. Should at minimum:

    • Log the error to ledger
    • Surface to Human
    • Halt the close flow until a corrective path is taken

The combination is dangerous: the server's role enforcement is working, but it's invisible because bro hides the rejection.

Trace

CC session log: ~/.claude/projects/-private-tmp-tmb-marketplace/fccc58b7-1030-4a99-b499-88dfd9bdc415.jsonl line items 23 (validation_record call) → 21 (task_update_status closed) → 22 (issue_close) — all in one turn, no error surfaced to Human.

Fix proposal

In bro's CLAUDE.md task-gate doctrine, add:

If any MCP call returns is_error:true, you MUST surface the exact error to the Human. Never silently proceed to subsequent steps as if the call succeeded.

And in the planning skills, remove any guidance that suggests bro call validation_record — that's pr-reviewer-only. Bro writes ledger_log(event_type='bro_verification_pass') instead (#91).

Related

Found during cold-session dogfood test 3 of marketplace install of tmb-rc@0.3.2.

Metadata

Metadata

Assignees

Labels

BugSomething isn't workingDoctrineDoctrine clarification or contract changePriority: HighHigh priority — blocks meaningful workflowsWorkflowBro / SWE / pr-reviewer doctrine + planning skills

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions