Skip to content

Fix BadResource errors in subprocess HTTP/2 cleanup#82

Merged
lambdalisue merged 1 commit intomainfrom
fix/bad-resource
Jan 5, 2026
Merged

Fix BadResource errors in subprocess HTTP/2 cleanup#82
lambdalisue merged 1 commit intomainfrom
fix/bad-resource

Conversation

@lambdalisue
Copy link
Member

Summary

  • Make IpcConnection.close() async to properly flush pending writes
  • Reorder parent-subprocess cleanup to wait for subprocess exit first
  • Add unhandledrejection handler to suppress node:http2 BadResource errors
  • Match Worker-based execution's error suppression strategy

Why

After migrating from Worker to subprocess execution, HTTP/2-based scenarios
(HTTP client, GraphQL, etc.) were failing with "BadResource: Bad resource ID"
errors from node:http2. These errors occurred during HTTP/2 stream cleanup when
the subprocess terminated.

The root causes were:

  1. Premature resource cleanup: Parent process closed IPC connection before
    subprocess finished writing results
  2. Abandoned writes: IpcConnection.close() didn't await writer.close(),
    leaving pending writes in limbo
  3. Timing issues: HTTP/2 streams require proper finalization time

This PR implements a two-layer solution:

  1. Proper resource management (commit d820216): Await writer.close() and
    reorder cleanup to ensure subprocess completes before IPC closes
  2. Error suppression (commit 6ab6d0c): Add unhandledrejection handler
    matching the Worker-based approach, as HTTP/2 cleanup errors don't affect
    test correctness

The combination ensures both correct resource lifecycle management and graceful
handling of unavoidable node:http2 cleanup errors.

Test Plan

  • Run deno task verify - all tests pass
  • Test HTTP/2-based scenarios (HTTP client, GraphQL) - no BadResource errors
  • Verify error suppression only affects node:http2 BadResource errors
  • Confirm other unhandled rejections are still logged

Copilot AI review requested due to automatic review settings January 5, 2026 05:38
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes BadResource errors occurring during subprocess HTTP/2 cleanup by implementing proper resource lifecycle management and error suppression. The fix involves making IPC connection cleanup async to flush pending writes, reordering cleanup operations to wait for subprocess exit before closing connections, and adding an unhandledrejection handler to suppress unavoidable node:http2 cleanup errors.

Key changes:

  • Made IpcConnection.close() and closeIpc() async to properly await writer flushing
  • Reordered cleanup in parent process to wait for subprocess exit before closing IPC
  • Added unhandledrejection handler in run.ts subprocess to suppress node:http2 BadResource errors

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/cli/commands/run.ts Reordered cleanup to await subprocess exit before closing IPC connection
src/cli/commands/list.ts Reordered cleanup to await subprocess exit before closing IPC connection
src/cli/_templates/utils.ts Made IpcConnection.close() and closeIpc() async to properly flush pending writes
src/cli/_templates/run.ts Added unhandledrejection handler for node:http2 errors and updated closeIpc() call to await
src/cli/_templates/list.ts Updated closeIpc() call to await the async operation

Critical Issues Found:

There are two critical bugs where the async ipc.close() method is not being awaited in the parent process cleanup code. This defeats the purpose of making the close operation async, as pending writes may not be properly flushed before cleanup continues. The subprocess templates correctly await the close operation, but the parent process files (run.ts and list.ts in commands/) need to be updated to also await this call.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

The subprocess IPC connection was being closed before the subprocess
finished writing, causing "Bad resource ID" errors when the subprocess
tried to write to an already-closed TCP stream. This also caused benign
unhandled rejections from Deno's node:http2 compatibility layer during
HTTP/2 stream cleanup.

Changes:
- Made closeIpc() and IpcConnection.close() async to ensure writer is
  properly flushed before closing the underlying TCP connection
- Reordered cleanup sequence in run/list commands: wait for subprocess
  exit first, then close IPC, then close listener
- Added unhandled rejection handler in subprocess to gracefully suppress
  benign "Bad resource ID" errors from node:http2 cleanup

This ensures all pending IPC writes complete before resource cleanup.
@lambdalisue lambdalisue merged commit e5fb7c1 into main Jan 5, 2026
4 checks passed
@lambdalisue lambdalisue deleted the fix/bad-resource branch January 5, 2026 05:56
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