Skip to content

safeoutputs gateway registers 0 tools → every safe-output call fails "unknown tool" → silent green no-op (reproduces on v0.82.9, after #43057) #46184

Description

@matiloti

Summary

The safeoutputs MCP gateway intermittently registers zero tools, causing every safe-output call (push_to_pull_request_branch, add_comment, add_labels, and even noop / report_incomplete) to fail with unknown tool. Because there is no working channel to emit anything — including the failure-reporting escape hatches — the run finishes as a green success / no-op with the outage completely hidden.

This reproduces on v0.82.9, i.e. after #43057 ("Fail fast on empty safeoutputs schema", merged 2026-07-07). That fix's two guards did not help here, because:

  1. The tools.json "recovery" is a false positive, not a real recovery. Fail fast on empty safeoutputs schema and add Copilot soft-time convergence guard #43057 re-derives the schema from GH_AW_SAFE_OUTPUTS_TOOLS_PATH when tools/list is empty and logs recovered N tool(s) from .../tools.json. But that only repopulates the CLI help/docs — the live gateway session still advertises "tools":[], so every actual call still fails unknown tool. And because recovery "succeeded" (tools.json had 9 entries), the "if still empty, fail early" branch never triggers — the run proceeds degraded exactly as before the fix.
  2. A total safeoutputs outage is indistinguishable from an intentional no-op. With no outputs.jsonl written, the conclusion path reports treating as empty collection (graceful no-op)success. The self-report tools (noop, report_incomplete) are themselves safeoutputs tools, so they hit the same wall and the failure can never surface. (Fail fast on empty safeoutputs schema and add Copilot soft-time convergence guard #43057's Copilot soft-time guard also emits report_incomplete — which is likewise a safeoutputs tool, so it too would fail unknown tool here.)

Environment

  • gh-aw ~v0.82.9 (setup-cli@v0.82.9, firewall agent 0.25.29), engine copilot (CLI 1.0.70), network isolation (sandbox.agent.sudo: false).
  • Running on GitHub Enterprise Server (GH_HOST set), self-hosted runner.
  • Workflow: an issue_comment-triggered PR-triage agentic workflow.

What happened (timeline from the run logs)

  1. The MCP gateway failed its health check 38 times (ECONNRESET / socket hang up) before finally passing on attempt 39 (~40s):
    [warning] MCP gateway health check failed (attempt 38/120): read ECONNRESET
    [info] ✓ MCP gateway health check succeeded on retry attempt 39
    
  2. At mount time, safeoutputs served an empty tool list; the "recovery" fired:
    ##[warning] safeoutputs tools/list returned empty; recovered 9 tool(s) from .../safeoutputs/tools.json
    
  3. Despite the "recovery", the live gateway (awmg-mcpg:8080/mcp/safeoutputs) still advertised "tools":[] while the github gateway correctly had 25 tools. Every safeoutputs call returned unknown tool, across ~2 minutes of retries and multiple recovery approaches by the agent:
    Every tool returns "unknown tool", including `noop`. This is a bridge/gateway issue, not specific to push.
    safeoutputs registered 0 tools while github has 25.
    
  4. The agent even ran the safeoutputs server itself locally and generated a valid 9,287-byte push patch, but couldn't emit it — writing the output file failed because the location is only writable by the privileged gateway:
    EROFS: read-only file system  (writing outputs.jsonl)
    
  5. Conclusion, with no outputs.jsonl ever written:
    Output file does not exist: .../safeoutputs/outputs.jsonl — no safe-output items were emitted; treating as empty collection (graceful no-op)
    Agent output content length: 24
    Found 0 message(s) in agent output
    Agent succeeded but produced no safe outputs
    
    → run reported success, no comment / no push / no label / no error surfaced.

Why this is bad

A complete safe-outputs outage is laundered into a clean-looking green no-op. From the outside it is indistinguishable from "the agent decided there was nothing to do." The agent had actually done the work and produced a valid patch — it just had no channel to deliver it or to report that it was blocked.

Suggested fixes

Related

Happy to provide the full run log / artifacts on request.

Metadata

Metadata

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions