Skip to content

A Cloudflare 502 HTML page reaches the retained-run contract parser as the failure reason #1203

Description

@drewstone

What happened

mech-interp-foundations-glm2-20260911e (agent-runtime 0.217.1, agent-provider-tangle 1.1.11) lost a child to this, and the reason recorded in result.json and printed by disco report is a full Cloudflare error page:

1x infra: retained provider execution requires reconciliation before replacement:
  caused by RetainedRunProviderContractError: <!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en-US"> <![endif]-->
...
<title>tangle.tools | 502: Bad gateway</title>

The runner log shows the transport layer seeing it correctly first:

[sandbox-sdk] Stream dropped without terminal event, reconnecting (attempt 1/6)
[sandbox-sdk] Replay endpoint returned 502, attempt 1
[sandbox-sdk] Stream dropped without terminal event, reconnecting (attempt 2/6)

So the replay endpoint answered 502 with an HTML body, the SDK retried, and somewhere above it the body was carried into a contract error verbatim instead of being classified as a transport failure.

Why it is worth fixing

Two costs, both measured on this run:

  1. The reason is unreadable. A settlement reason is the operator's primary signal (disco report ranks failures by it). Several hundred bytes of Cloudflare markup crowds out the cause, and the three children that stalled behind it read as an unexplained retained-execution failure. This lane spent three days on a defect that was invisible for exactly this reason.
  2. It is classified wrong. A 502 from a gateway is a transport failure that the caller should retry or settle as driver-failed; RetainedRunProviderContractError says the provider returned something that violates its contract, which invites reconciliation of an execution that never started.

Suggested shape

Where the retained-run response is parsed, check the content type and status before parsing: a non-JSON body, or any 5xx, is a transport failure carrying the status and a bounded excerpt (say the first 200 characters, with the HTML stripped or the <title> extracted), not a contract violation. The provider already classifies other transport errors this way; this is the path that misses it.

Related: agent-runtime 0.213.0 (#1188) added the cause chain to a down settlement's reason, which is how this text became visible at all. This is the follow-on — the chain is right, one link in it is a web page.

Evidence retained at discovery-lab@master:pursuits/mech-interp-foundations-glm2-20260911e (journal, result, runner log).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions