Skip to content

fix(workflow-executor): say why an automated inbox read or route failed - #1942

Merged
Scra3 merged 1 commit into
feature/prd-1183-runtime-automation-pollerfrom
feature/prd-1300-poller-observability
Sep 30, 2026
Merged

Scra3 merged 1 commit into
feature/prd-1183-runtime-automation-pollerfrom
feature/prd-1300-poller-observability

Conversation

@Scra3

@Scra3 Scra3 commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

fixes PRD-1300
fixes PRD-1301
fixes PRD-1302

Why

Three failures of the automation poller left nothing to act on in the customer's runtime logs:

  • PRD-1300: an inbox listed by GET /automated-inboxes, then answering 404 on its own assignments or sync route, was logged at Info with no reason. A route missing behind a proxy, a path prefix or a version skew looks exactly like that, and the inbox is then never swept again.
  • PRD-1301: a refused segment read logged only Agent responded with HTTP 400. A renamed segment, a lost permission and an unsupported operator all read the same.
  • PRD-1302: an unreadable listing envelope returned [], so a server-side reshape read as an environment with no automated inbox at all.

What

  • 404 on an inbox route: AutomatedInboxGoneError now carries the operation that answered 404 (listAutomatedInboxAssignments or syncAutomatedInbox) and the server's detail (errors[0].detail). The poller logs it at Warn: Automated inbox listed this cycle but its route answered 404, dropping it for this cycle. The inbox is still dropped for this cycle only.

  • Refused segment read: the Could not read … of an automated inbox log now carries:

    The three fallback Warns (not_in refused, later padded page failed, capabilities unreadable) carry the same fields.

  • Unreadable listing: listAutomatedInboxes throws Unreadable automated inbox listing from <forestServerUrl>: <zod issues>, so the cycle fails as Automation poll cycle failed, like listAssignments does. One unreadable config inside a readable envelope is still skipped on its own. A 404 on the listing route still returns [] (an orchestrator older than automated inboxes).

The lease heartbeat is independent of the sweep, so a failed cycle keeps the lease, and the next sweep runs one interval later. The existing test should keep polling after a cycle that threw covers this.

No server ↔ runtime contract change.

Security

agentError comes from agent-client's extractErrorDetail. It holds only the recognised error fields (errors[0].detail/message/title, error, message), flattened to one line and cut at 500 characters. It never holds the raw responseText (tested with an HTML body) or any header or token.

Unlike #1926, this detail is now logged on a 4xx too, because a 4xx is exactly the case this fixes. It is logged only by the poller, in the customer's own runtime logs. AgentPortError.message still carries the agent detail on 5xx only (a test guards this), and the user message is unchanged. At worst, a 4xx detail echoes a filter value or a record id, which the poller already logs elsewhere.

How it was checked

  • Each new test fails without the behaviour it covers: 18 mutations were applied to the source one at a time (Info level, dropped fields, return [], a 5xx gate on the detail, 0-based chunk index…), and every one fails at least one test.
  • workflow-executor suite green (2021 tests), lint and typecheck clean.
  • Reviewed with Opus before the first push.

Definition of Done

General

  • Write an explicit title for the Pull Request, following Conventional Commits specification
  • Test manually the implemented changes
  • Validate the code quality (indentation, syntax, style, simplicity, readability)

Security

  • Consider the security impact of the changes made: see the Security section above.

🤖 Generated with Claude Code

Note

Add operation and agent-detail context to automated inbox read/route failures

  • Failed inbox reads and routes now log the failed operation, classified HTTP status, sanitized agent detail, and query progress (membership chunk index/total, page size, page number, not_in mode, padding reason) via a new describeAgentFailure helper in automation-poller.ts
  • agentErrorDetail in errors.ts is now public and extracts sanitized structured detail from AgentPortError causes or 4xx responses without falling back to raw response text
  • AutomatedInboxGoneError now carries the failed operation name and extracted detail; the poller logs it at Warn before dropping the inbox for the cycle
  • Behavioral Change: an invalid automated-inbox response envelope now makes listAutomatedInboxes reject with the Forest server URL and schema message instead of resolving to an empty inbox list — see parseConfigs in forest-server-automation-port.ts

Macroscope summarized c580544.

A 404 on an inbox route listed this cycle is logged at Warn with the
operation and the server's reason. A refused segment read logs its HTTP
status, the agent's error message (cut at 500 chars, never the raw body)
and the parameters of the read. An unreadable inbox listing fails the
cycle instead of reading as an environment with no inbox.

fixes PRD-1300
fixes PRD-1301
fixes PRD-1302

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@linear-code

linear-code Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

PRD-1302

PRD-1301

PRD-1300

@qltysh

qltysh Bot commented Sep 30, 2026

Copy link
Copy Markdown

7 new issues

Tool Category Rule Count
qlty Structure Function with many returns (count = 4): reconcileClosed 2
qlty Structure Function with high complexity (count = 14): reconcileClosed 2
qlty Structure Function with many parameters (count = 4): readCandidates 2
qlty Structure High total complexity (count = 90) 1

@qltysh

qltysh Bot commented Sep 30, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

This PR will not change total coverage.

Modified Files with Diff Coverage (3)

RatingFile% DiffUncovered Line #s
Coverage rating: A Coverage rating: A
packages/workflow-executor/src/automation-poller.ts100.0%
Coverage rating: A Coverage rating: A
...orkflow-executor/src/adapters/forest-server-automation-port.ts100.0%
Coverage rating: A Coverage rating: A
packages/workflow-executor/src/errors.ts100.0%
Total100.0%
🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@matthv matthv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. One gap: no test pins pageNumber / notIn when a later padded page fails (e.g. not_in refused, page 1 ok, page 2 fails), so a stale pageNumber: 1 would pass.

@Scra3
Scra3 merged commit 7e9a283 into feature/prd-1183-runtime-automation-poller Sep 30, 2026
37 checks passed
@Scra3
Scra3 deleted the feature/prd-1300-poller-observability branch September 30, 2026 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants