Skip to content

fix: prevent callback shutdown from blocking login - #265

Merged
jlitola merged 3 commits into
mainfrom
jlitola/fix-sandbox-no-browser
Aug 9, 2026
Merged

fix: prevent callback shutdown from blocking login#265
jlitola merged 3 commits into
mainfrom
jlitola/fix-sandbox-no-browser

Conversation

@jlitola

@jlitola jlitola commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • force-close temporary OAuth callback connections after the browser response finishes or closes
  • continue token exchange, credential persistence, timeout reporting, and callback-error reporting without awaiting listener teardown
  • cover proxied keep-alive callbacks, close-before-finish responses, and non-resolving shutdown with regressions
  • document callback shutdown behavior for remote environments

Root cause

The login flow awaited HTTP server close before exchanging the authorization code. A sandbox port proxy could keep the callback connection alive after rendering the success page, leaving init blocked indefinitely. The callback result also depended only on the response finish event, so an early connection close could leave a valid callback unsettled.

Review follow-up

  • settle callback results on both response finish and close
  • make listener cleanup non-blocking on success, callback error, and timeout paths
  • remove the test-only CallbackServerHandle port field
  • make shutdown-order assertions explicit and add real listener regressions
  • harden callback socket tests against probe/rebind collisions and limit the response prototype spy to the request window

The Biome schema alignment and removal of a forbidden non-null assertion are validation-only cleanup surfaced by this change; they do not affect callback behavior.

Validation

  • bun run format:check
  • bun run lint
  • bun run typecheck
  • bun test (2579 passing)
  • callback socket regressions repeated 20 times (40 passing)
  • bun run build
  • bun run plugins:generate
  • bun run plugins:check
  • bun run smoke:cli (70 steps, authenticated live smoke passed)
  • bun run smoke:mcp (38 steps, authenticated live smoke passed)
  • bun run smoke:cli:built
  • bun run smoke:mcp:built

Force-close temporary callback connections after the response finishes and continue token exchange without awaiting listener teardown. Add keep-alive and orchestration regression coverage for proxied sandbox logins.
@jlitola jlitola added the bug Something isn't working label Aug 9, 2026
Resolve valid callbacks when the response closes before finish, and keep timeout and callback-error reporting independent from listener teardown. Remove the test-only callback port field and strengthen shutdown ordering coverage.
@jlitola

jlitola commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the Fable review in b31d724:

  • callback result now settles on response finish or close
  • shutdown is non-blocking on callback failure and timeout paths too
  • removed CallbackServerHandle.port
  • cleaned up the ordering test so assertions cannot be swallowed
  • added deterministic close-before-finish and non-resolving-close regressions

I retained the Biome schema alignment and non-null cleanup, and called them out explicitly in the PR body because reverting them restores current lint diagnostics.

Final deterministic validation passes. The live authenticated backend was unhealthy during rerun (MCP 60s timeout; CLI request stalled beyond five minutes); this is recorded in the PR body.

Retry the probe-and-rebind test setup on EADDRINUSE and limit the response prototype spy to the request window it must control.
@jlitola

jlitola commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

Addressed both round-2 test findings in 84ef745:

  • callback test startup now retries the probe/close/rebind sequence up to three times, and only for EADDRINUSE
  • the ServerResponse.end spy is installed only after server startup and socket connection, immediately before socket.write
  • added a comment explaining why the response is destroyed server-side to deterministically exercise close without finish

Validation: 2579 tests pass, focused socket regressions pass 40/40, formatting/lint/types pass, build passes, and generated plugin assets validate.

@jlitola

jlitola commented Aug 9, 2026

Copy link
Copy Markdown
Contributor Author

Live smoke rerun passed on the host after respecting the backend rate-limit cooldown:

  • bun run smoke:cli — passed all 70 steps, including authenticated live calls and CLI/MCP JSON parity
  • bun run smoke:mcp — passed all 38 steps, including authenticated live calls

The PR validation section has been updated to replace the earlier backend-timeout/rate-limit note.

@jlitola
jlitola merged commit 671ed73 into main Aug 9, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant