Skip to content

fix(opencode): retry DNS failures and identify terminal responses - #48

Draft
kevoconnell wants to merge 1 commit into
devfrom
codex/dns-terminal-delivery
Draft

kevoconnell wants to merge 1 commit into
devfrom
codex/dns-terminal-delivery

Conversation

@kevoconnell

@kevoconnell kevoconnell commented Sep 17, 2026

Copy link
Copy Markdown

Connected-chat requests can recover from a transient DNS lookup failure instead of silently ending, and completion notifications now identify the saved response they belong to. This prevents reply consumers from treating an older answer as the result of a failed turn.

The investigation started from this stuck Slack conversation. A related Messages incident showed getaddrinfo ETIMEOUT ending a request without retry; the deployed processor emitted error/idle before persisting its failed assistant message. The earlier Slack replay stall is a separate finding; this PR does not claim to identify its original blocking operation.

Changes

  • Recognize transient getaddrinfo ETIMEOUT, ETIMEDOUT, and EAI_AGAIN errors. Permit at most two retries using the existing backoff, while honoring a stricter configured budget. Permanent hostname errors and unrelated unknown errors retain their existing behavior.
  • Persist final assistant data before publishing a terminal failure. Add optional messageID to error and idle events so consumers can select that response through replay.
  • Track the completed message through normal prompt and shell completion, retaining its identity for duplicate idle notifications and clearing it when a new run starts.
flowchart TD
    Request[Model connection] --> Retry[Bounded transient DNS retry]
    Retry --> Saved[Save assistant result and final parts]
    Saved --> Terminal[Error or idle carries message ID]
    Terminal --> Delivery[Consumer settles the identified response]
Loading

The companion Andytown #27806 consumes the optional identity and deduplicates outbound completion delivery. Deploy consumers before rolling out this runtime. A persistent DNS outage now adds two retry delays (2 and 4 seconds), plus lookup time, before reporting failure. This PR requires a normal Replopencode release and sandbox upgrade; it does not change live sandboxes. Rollback is restoring the previous runtime pin; the wire fields are additive.

Testing Done

  • bun test test/session/retry.test.ts: 45 passed, including transient/permanent DNS classification and bounded exhaustion.
  • bun test test/session/processor-effect.test.ts: 19 passed, including saved failed-message data and matching terminal identity at notification time.
  • bun test test/session/prompt.test.ts: 61 passed, 1 existing skip, covering follow-ups, shell execution, and cancellation.
  • Repeated all three suites with the repository-pinned Bun 1.3.14: 125 passed, 1 existing skip, 0 failed.
  • bun typecheck in packages/opencode: passed.
  • The pre-push monorepo typecheck passed all 30 package checks.
  • Client and legacy SDK generation: passed. Legacy SDK generation also synchronizes the already-defined promptCacheKey option.
  • Scoped oxlint: no errors; 8 warnings remain on unchanged code. git diff --check: passed.

Summary by cubic

Retries transient DNS lookup failures instead of ending the request, and makes terminal error/idle events carry the messageID of the saved assistant response so reply consumers no longer settle on an older answer.

Transient getaddrinfo ETIMEOUT, ETIMEDOUT, and EAI_AGAIN errors now retry up to twice with the existing backoff, capped by any configured retry budget. Failed assistant messages are persisted before the terminal event fires, and session.error/session.idle events include an optional messageID. Permanent hostname errors and unrelated errors keep the previous behavior.

Deployment

  • Deploy the companion andytown consumer before rolling out this runtime.
  • A persistent DNS outage adds two retry delays (2 and 4 seconds) plus lookup time.
  • Requires a normal Replopencode release and sandbox upgrade; rollback is restoring the previous runtime pin.

Written for commit 47d938b. Summary will update on new commits.

Review in cubic

@github-actions

Copy link
Copy Markdown

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown

The following comment was made by an LLM, it may be inaccurate:

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant