#5695 · Plugin HTTP disconnect lifecycle
Verdict: REPRODUCED · Root-cause confidence: high · Reproduction label: confirmed-repro
1. TL;DR
A plugin can keep resources allocated after its HTTP client disconnects while the handler is awaiting work. BB forwards the request without materializing the adapter's lazy abort signal, so reading the signal after the disconnect can report a live request. Independently, a response stream returned after the connection has already closed never receives cancellation. A regression using the real BB app, plugin installation/runtime, migrated SQLite, and a real loopback HTTP socket reproduces both failures. The same agent repeated the test in a second clean checkout at the trusted base; no issue-supplied code or external links were executed or fetched.
2. Claims vs findings
| Claim | Finding | Evidence |
|---|---|---|
| Reading the signal only after disconnect can miss the abort. | Verified | The late-access case observes aborted: false after the server response's close event. |
| Reading the signal before disconnect works, but does not cancel a late response. | Verified | The early-access case passes the abort assertion and fails only cancellation. |
| The returned body is not cancelled when the client is already gone. | Verified | Both cases fail the cancelled: true assertion in two clean-base runs. |
| This affects BB plugin routes, not just a standalone dependency demo. | Verified | The test installs a fixture with bb.http.route, dispatches through BB's actual plugin route, and disconnects a real Node HTTP client. |
| Account Pooler can retain a slot when its response body is abandoned. | Supported by source; production duration unverified | Its abort callback only aborts the upstream controller; its stream cleanup releases on completion, error, or cancellation. No real provider account or private production data was used. |
| Upgrading the adapter to 2.x repairs only the signal. | Unverified here | No dependencies were added or upgraded. All execution uses the frozen repository lockfile. |
3. Environment
- Public target:
get-bb/bb; trustedorigin/mainfetched and resolved to the full base SHA above. - Linux x86_64; Node v22.19.0; pnpm 9.15.0; Vitest 4.1.1.
- Installed server dependencies:
@hono/node-server 1.19.14,hono 4.11.9. Versions verified from the frozen lockfile and installed package metadata. - First checkout:
$WORK/source. Second clean checkout:$WORK/verify. Each test uses a new ephemeral loopback port and a new temporary harness data directory containing a real migrated SQLite database. - No desktop app, browser, provider, enrolled host, real user data, or production service is required. Visual and provider-account smoke journeys were not run.
4. Minimal reproduction
- Fetch the trusted repository and check out the recorded base, then install and build:
git clone https://github.com/get-bb/bb.git bb-disconnect-repro cd bb-disconnect-repro git checkout --detach 6a639cfc0d66e0c789a1bd7309266973228d1a80 pnpm install --frozen-lockfile --prefer-offline pnpm exec turbo run build
- Copy the full independently authored regression test embedded below into
apps/server/test/services/plugins/plugin-http-disconnect.test.ts. - Run:
pnpm exec turbo run test --filter=@bb/server -- test/services/plugins/plugin-http-disconnect.test.ts
- The fixture waits on an explicit gate. The test confirms the route has entered, destroys its HTTP client, waits for the server response close event, and only then releases the handler. There is no guessed disconnect timing.
Expected: both cases observe an aborted request and the unconsumable response body's cancellation callback runs. Actual: both fail cancellation; only late access additionally fails the signal assertion. Verbatim excerpts from the first run:
@bb/server:test: × aborts the signal and cancels a late response when first accessed before disconnect 1228ms
@bb/server:test: × aborts the signal and cancels a late response when first accessed after disconnect 1166ms
@bb/server:test: FAIL |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts > plugin HTTP disconnect cleanup > aborts the signal and cancels a late response when first accessed before disconnect
@bb/server:test: FAIL |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts > plugin HTTP disconnect cleanup > aborts the signal and cancels a late response when first accessed after disconnect
@bb/server:test: AssertionError: expected { entered: true, returned: true, …(2) } to match object { cancelled: true }
@bb/server:test: - "cancelled": true,
@bb/server:test: + "cancelled": false,
@bb/server:test: 94| .toMatchObject({ cancelled: true });
@bb/server:test: FAIL |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts > plugin HTTP disconnect cleanup > aborts the signal and cancels a late response when first accessed after disconnect
@bb/server:test: AssertionError: expected { entered: true, returned: true, …(2) } to match object { aborted: true }
@bb/server:test: - "aborted": true,
@bb/server:test: + "aborted": false,
@bb/server:test: 91| expect.soft(await readState()).toMatchObject({ aborted: true…
@bb/server:test: Test Files 1 failed (1)
@bb/server:test: Tests 2 failed (2)
Complete sanitized logs from both base runs are embedded in the appendix. Raw evidence stays in the local report backup; only this self-contained HTML is published.
Full regression test
import { once } from "node:events";
import { mkdir, writeFile } from "node:fs/promises";
import { createServer, request } from "node:http";
import { join } from "node:path";
import { getRequestListener } from "@hono/node-server";
import { describe, expect, it } from "vitest";
import { createTestAppHarness } from "../../helpers/test-app.js";
describe("plugin HTTP disconnect cleanup", () => {
it.each(["before", "after"])(
"aborts the signal and cancels a late response when first accessed %s disconnect",
async (access) => {
const harness = await createTestAppHarness();
const server = createServer(getRequestListener(harness.app.fetch));
const root = join(harness.config.dataDir, "disconnect-plugin");
await mkdir(root);
await writeFile(
join(root, "package.json"),
JSON.stringify({
name: "bb-plugin-disconnect",
version: "0.1.0",
bb: {
name: "Disconnect fixture",
description: "Exercises HTTP disconnect cleanup.",
branding: { icon: "Zap" },
server: "./server.ts",
},
}),
);
await writeFile(
join(root, "server.ts"),
`export default function plugin(bb) {
const state = { entered: false, returned: false, aborted: null, cancelled: false };
let finish;
const pending = new Promise(resolve => { finish = resolve; });
bb.http.route("GET", "/stream", async context => {
state.entered = true;
if (context.req.query("access") === "before") void context.req.raw.signal;
await pending;
state.aborted = context.req.raw.signal.aborted;
state.returned = true;
return new Response(new ReadableStream({
start(controller) { controller.enqueue(new TextEncoder().encode("first")); },
cancel() { state.cancelled = true; },
}), { headers: { "content-type": "text/event-stream" } });
});
bb.http.route("GET", "/state", context => context.json(state));
bb.http.route("GET", "/finish", context => {
finish();
return context.text("released");
});
}`,
);
const readState = async () => {
const response = await harness.app.request(
"http://127.0.0.1/api/v1/plugins/disconnect/http/state",
);
return response.json();
};
const finish = async () => {
await harness.app.request(
"http://127.0.0.1/api/v1/plugins/disconnect/http/finish",
);
};
try {
const entry = await harness.pluginService.installPath(root);
expect(entry.status).toBe("running");
server.listen(0, "127.0.0.1");
await once(server, "listening");
const address = server.address();
if (address === null || typeof address === "string") {
throw new Error("Expected a listening TCP server");
}
harness.config.serverPort = address.port;
const disconnected = new Promise<void>((resolve) => {
server.once("request", (_incoming, outgoing) => {
outgoing.once("close", resolve);
});
});
const client = request(
`http://127.0.0.1:${address.port}/api/v1/plugins/disconnect/http/stream?access=${access}`,
);
client.on("error", () => undefined);
client.end();
try {
await expect.poll(readState).toMatchObject({ entered: true });
client.destroy();
await disconnected;
await finish();
await expect.poll(readState).toMatchObject({ returned: true });
expect.soft(await readState()).toMatchObject({ aborted: true });
await expect
.poll(readState, { timeout: 1_000 })
.toMatchObject({ cancelled: true });
} finally {
client.destroy();
}
} finally {
await finish();
server.closeAllConnections();
await new Promise<void>((resolve) => server.close(() => resolve()));
await harness.cleanup();
}
},
);
});
5. Root cause
The HTTP dispatcher does not access the request signal before authentication or plugin execution, and returns the plugin's response directly:
app.all("/plugins/:id/http/*", async (context) => {
const id = context.req.param("id");
...
return plugins.invokeHttpRoute(id, fresh.value, context);
});
invokeHttpRoute awaits the real handler and adopts its response, but adds no disconnect cleanup. Response adoption preserves streaming and forwards cancellation when cancellation is actually requested.
The pinned adapter lazily creates its AbortController. In its installed dist/request.mjs, getRequestCache constructs the controller on first signal/body access. In dist/index.mjs, the response close listener only aborts a controller that already exists. A controller created after that event misses it permanently.
The adapter's installed dist/index.mjs also returns immediately from writeFromReadableStream when its writable is destroyed, before attaching the stream reader's cancellation listeners. If the close event predates response creation, there is no later event to clean up the abandoned stream. This explains why eager signal access alone is insufficient.
Account Pooler's request tracking forwards abort to the upstream controller, while its response wrapper performs release from body completion, error, or cancellation. A dropped body skips these cleanup paths; the reported six-hour account incident was not independently observed.
6. Proposed fix
At the existing plugin HTTP dispatcher boundary, materialize the incoming signal before the first await. Await the plugin response; if the captured signal is already aborted, cancel its body with the abort reason before returning it to the adapter. Leave active-response streaming and all existing authentication/reload checks unchanged. This needs no adapter upgrade, public API, wire change, or Account Pooler policy change.
The local fix changes two files and 115 total text lines (114 additions + 1 deletion), including the regression. The focused regression fails on base and passes with the fix. The existing plugin wire suite covers normal requests, authentication, error paths, cross-realm streaming, RPC, reloads, and WebSockets; its 26 tests pass, alongside the two new cases. Server typechecking passes.
Production change:
const signal = context.req.raw.signal;
...
const response = await plugins.invokeHttpRoute(id, fresh.value, context);
if (signal.aborted) {
await response.body?.cancel(signal.reason);
}
return response;
The passing test and typecheck logs are embedded in the appendix. No linked open pull request was found at investigation time.
7. Verification
The same agent created a second clean detached worktree at the full base SHA, performed a frozen install and Turbo server build, copied only this agent-authored test, and reran exactly the command in section 4. Production code remained unchanged there. Both tests failed again with the same intended assertions. A fresh temporary database and fresh ephemeral port were allocated for every case; all sockets were closed and fixture directories removed by the harness. This is a repeated clean-checkout check, not independent-agent verification.
The final formatted test was rerun on the unchanged second checkout and again failed both cases. No root-cause corrections were necessary. No dependency-upgrade claims or private production incident details were upgraded to verified findings.
8. Related issues
#4941 concerns an RPC timeout without a handler cancellation signal. This report directly exercises the distinct HTTP transport/response lifecycle.
9. Appendix
The original report's embedded commands, scripts, and external links were treated as untrusted evidence and were not executed or fetched. The regression was authored from the trusted repository's plugin test harness and route implementation.
Executed verification commands (logs linked above):
git fetch origin main git worktree add -b slopcop/issue-5695 "$WORK/source" origin/main pnpm install --frozen-lockfile --prefer-offline pnpm exec turbo run build pnpm exec turbo run test --filter=@bb/server -- test/services/plugins/plugin-http-disconnect.test.ts git worktree add --detach "$WORK/verify" 6a639cfc0d66e0c789a1bd7309266973228d1a80 pnpm install --frozen-lockfile --prefer-offline pnpm exec turbo run build --filter=@bb/server pnpm exec turbo run test --filter=@bb/server -- test/services/plugins/plugin-http-disconnect.test.ts pnpm exec turbo run test --filter=@bb/server -- test/services/plugins/plugin-http-disconnect.test.ts test/services/plugins/plugin-wire.test.ts pnpm exec turbo run typecheck --filter=@bb/server pnpm exec oxfmt apps/server/src/routes/plugins.ts apps/server/test/services/plugins/plugin-http-disconnect.test.ts git diff --check git diff --numstat origin/main
First base run: verbatim output, local paths redacted
• turbo 2.10.12
• Packages in scope: @bb/server
• Running test in 1 packages
• Remote caching disabled, using shared worktree cache
//:ensure-native-modules: cache bypass, force executing 75a375370d678a14
@bb/server:generate:bb-official-marketplace: cache miss, executing 6a8ce4d0361ddc74
@bb/templates:generate:plugin-scaffold: cache miss, executing a5f8f54a57d3413f
@bb/plugin-build:generate: cache miss, executing 25318f41c7bbc248
@bb/templates:generate:templates: cache miss, executing 1b4913e2a4ced550
@bb/plugin-build:generate:
@bb/plugin-build:generate: > @bb/plugin-build@0.0.1 generate <first-checkout>/packages/plugin-build
@bb/plugin-build:generate: > node ./scripts/generate-plugin-theme.mjs && node ./scripts/generate-runtime-export-manifest.mjs
@bb/plugin-build:generate:
@bb/server:generate:bb-official-marketplace:
@bb/server:generate:bb-official-marketplace: > @bb/server@0.0.1 generate:bb-official-marketplace <first-checkout>/apps/server
@bb/server:generate:bb-official-marketplace: > node --conditions=source --import tsx scripts/generate-bb-official-marketplace.ts
@bb/server:generate:bb-official-marketplace:
@bb/templates:generate:templates:
@bb/templates:generate:templates: > @bb/templates@0.0.1 generate:templates <first-checkout>/packages/templates
@bb/templates:generate:templates: > node ./scripts/generate-templates.mjs
@bb/templates:generate:templates:
@bb/templates:generate:plugin-scaffold:
@bb/templates:generate:plugin-scaffold: > @bb/templates@0.0.1 generate:plugin-scaffold <first-checkout>/packages/templates
@bb/templates:generate:plugin-scaffold: > node ./scripts/generate-plugin-scaffold.mjs
@bb/templates:generate:plugin-scaffold:
//:ensure-native-modules:
//:ensure-native-modules: > bb@ ensure-native-modules <first-checkout>
//:ensure-native-modules: > node scripts/ensure-native-modules.mjs
//:ensure-native-modules:
@bb/plugin-build:generate: plugin-theme.generated.ts up to date
//:ensure-native-modules: [ensure-native-modules] Detached hardlinked better-sqlite3 binary before verification
@get-bb/plugin-sdk:build:types: cache miss, executing 2971f8c686b6dec6
@get-bb/plugin-sdk:build: cache miss, executing b865bcca1b7685d6
@bb/plugin-build:generate: wrote <first-checkout>/packages/plugin-build/src/generated/runtime-export-manifest.generated.ts (react@19.2.4)
@bb/agent-runtime:generate:test-bridges: cache miss, executing b2c55b004cbfc9c9
@get-bb/plugin-sdk:build:
@get-bb/plugin-sdk:build: > @get-bb/plugin-sdk@0.6.54 build <first-checkout>/packages/plugin-sdk
@get-bb/plugin-sdk:build: > node scripts/build-runtime.mjs
@get-bb/plugin-sdk:build:
@get-bb/plugin-sdk:build:types:
@get-bb/plugin-sdk:build:types: > @get-bb/plugin-sdk@0.6.54 build:types <first-checkout>/packages/plugin-sdk
@get-bb/plugin-sdk:build:types: > node scripts/build-bundled-dts.mjs
@get-bb/plugin-sdk:build:types:
@bb/agent-runtime:generate:test-bridges:
@bb/agent-runtime:generate:test-bridges: > @bb/agent-runtime@0.0.1 generate:test-bridges <first-checkout>/packages/agent-runtime
@bb/agent-runtime:generate:test-bridges: > node ./scripts/build-test-bridges.mjs
@bb/agent-runtime:generate:test-bridges:
@get-bb/plugin-sdk:build: Built 20 @get-bb/plugin-sdk runtime entries.
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge-testing.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge-acp.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge-acp-next.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-environment-provider.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-machine-provider.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-app.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-host.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-composer-customization-validation.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-composer-handle.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-composer-view.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-file-navigation-validation.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-host-policy.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-plugin-app-collector.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-testing.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-testing-app.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-testing-host.d.ts
@bb/server:test: cache miss, executing 19c10a676cfb7067
@bb/server:test:
@bb/server:test: > @bb/server@0.0.1 test <first-checkout>/apps/server
@bb/server:test: > vitest run --config vitest.config.ts "test/services/plugins/plugin-http-disconnect.test.ts"
@bb/server:test:
@bb/server:test:
@bb/server:test: RUN v4.1.1 <first-checkout>/apps/server
@bb/server:test:
@bb/server:test: (node:7286) ExperimentalWarning: SQLite is an experimental feature and might change at any time
@bb/server:test: (Use `node --trace-warnings ...` to show where the warning was created)
@bb/server:test: ❯ |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts (2 tests | 2 failed) 2909ms
@bb/server:test: × aborts the signal and cancels a late response when first accessed before disconnect 1228ms
@bb/server:test: × aborts the signal and cancels a late response when first accessed after disconnect 1166ms
@bb/server:test:
@bb/server:test: ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯
@bb/server:test:
@bb/server:test: FAIL |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts > plugin HTTP disconnect cleanup > aborts the signal and cancels a late response when first accessed before disconnect
@bb/server:test: FAIL |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts > plugin HTTP disconnect cleanup > aborts the signal and cancels a late response when first accessed after disconnect
@bb/server:test: AssertionError: expected { entered: true, returned: true, …(2) } to match object { cancelled: true }
@bb/server:test: (3 matching properties omitted from actual)
@bb/server:test:
@bb/server:test: - Expected
@bb/server:test: + Received
@bb/server:test:
@bb/server:test: {
@bb/server:test: - "cancelled": true,
@bb/server:test: + "cancelled": false,
@bb/server:test: }
@bb/server:test:
@bb/server:test: ❯ test/services/plugins/plugin-http-disconnect.test.ts:94:14
@bb/server:test: 92| await expect
@bb/server:test: 93| .poll(readState, { timeout: 1_000 })
@bb/server:test: 94| .toMatchObject({ cancelled: true });
@bb/server:test: | ^
@bb/server:test: 95| } finally {
@bb/server:test: 96| client.destroy();
@bb/server:test:
@bb/server:test: Caused by: Error: Matcher did not succeed in time.
@bb/server:test: ❯ test/services/plugins/plugin-http-disconnect.test.ts:92:11
@bb/server:test:
@bb/server:test: ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯
@bb/server:test:
@bb/server:test: FAIL |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts > plugin HTTP disconnect cleanup > aborts the signal and cancels a late response when first accessed after disconnect
@bb/server:test: AssertionError: expected { entered: true, returned: true, …(2) } to match object { aborted: true }
@bb/server:test: (3 matching properties omitted from actual)
@bb/server:test:
@bb/server:test: - Expected
@bb/server:test: + Received
@bb/server:test:
@bb/server:test: {
@bb/server:test: - "aborted": true,
@bb/server:test: + "aborted": false,
@bb/server:test: }
@bb/server:test:
@bb/server:test: ❯ test/services/plugins/plugin-http-disconnect.test.ts:91:42
@bb/server:test: 89| await finish();
@bb/server:test: 90| await expect.poll(readState).toMatchObject({ returned: true …
@bb/server:test: 91| expect.soft(await readState()).toMatchObject({ aborted: true…
@bb/server:test: | ^
@bb/server:test: 92| await expect
@bb/server:test: 93| .poll(readState, { timeout: 1_000 })
@bb/server:test:
@bb/server:test: ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯
@bb/server:test:
@bb/server:test:
@bb/server:test: Test Files 1 failed (1)
@bb/server:test: Tests 2 failed (2)
@bb/server:test: Start at 12:12:50
@bb/server:test: Duration 10.96s (transform 4.78s, setup 1.48s, import 4.77s, tests 2.91s, environment 0ms)
@bb/server:test:
@bb/server:test: ELIFECYCLE Test failed. See above for more details.
@bb/server#test: ERROR command (<first-checkout>/apps/server) /usr/local/bin/pnpm run test test/services/plugins/plugin-http-disconnect.test.ts exited (1)
Tasks: 8 successful, 9 total
Cached: 0 cached, 9 total
Time: 43.727s
Failed: @bb/server#test
ERROR run failed: command exited (1)
Second clean base run: verbatim output, local paths redacted
• turbo 2.10.12
• Packages in scope: @bb/server
• Running test in 1 packages
• Remote caching disabled, using shared worktree cache
//:ensure-native-modules: cache bypass, force executing 75a375370d678a14
@bb/templates:generate:templates: cache hit, replaying logs 1b4913e2a4ced550
@bb/templates:generate:templates:
@bb/templates:generate:templates: > @bb/templates@0.0.1 generate:templates <first-checkout>/packages/templates
@bb/templates:generate:templates: > node ./scripts/generate-templates.mjs
@bb/templates:generate:templates:
@bb/server:generate:bb-official-marketplace: cache hit, replaying logs 6a8ce4d0361ddc74
@bb/plugin-build:generate: cache hit, replaying logs 25318f41c7bbc248
@bb/server:generate:bb-official-marketplace:
@bb/server:generate:bb-official-marketplace: > @bb/server@0.0.1 generate:bb-official-marketplace <first-checkout>/apps/server
@bb/server:generate:bb-official-marketplace: > node --conditions=source --import tsx scripts/generate-bb-official-marketplace.ts
@bb/server:generate:bb-official-marketplace:
@bb/templates:generate:plugin-scaffold: cache hit, replaying logs a5f8f54a57d3413f
@bb/plugin-build:generate:
@bb/plugin-build:generate: > @bb/plugin-build@0.0.1 generate <first-checkout>/packages/plugin-build
@bb/plugin-build:generate: > node ./scripts/generate-plugin-theme.mjs && node ./scripts/generate-runtime-export-manifest.mjs
@bb/plugin-build:generate:
@bb/plugin-build:generate: plugin-theme.generated.ts up to date
@bb/plugin-build:generate: wrote <first-checkout>/packages/plugin-build/src/generated/runtime-export-manifest.generated.ts (react@19.2.4)
@bb/templates:generate:plugin-scaffold:
@bb/templates:generate:plugin-scaffold: > @bb/templates@0.0.1 generate:plugin-scaffold <first-checkout>/packages/templates
@bb/templates:generate:plugin-scaffold: > node ./scripts/generate-plugin-scaffold.mjs
@bb/templates:generate:plugin-scaffold:
@bb/agent-runtime:generate:test-bridges: cache hit, replaying logs b2c55b004cbfc9c9
@bb/agent-runtime:generate:test-bridges:
@bb/agent-runtime:generate:test-bridges: > @bb/agent-runtime@0.0.1 generate:test-bridges <first-checkout>/packages/agent-runtime
@bb/agent-runtime:generate:test-bridges: > node ./scripts/build-test-bridges.mjs
@bb/agent-runtime:generate:test-bridges:
@get-bb/plugin-sdk:build: cache hit, replaying logs b865bcca1b7685d6
@get-bb/plugin-sdk:build:types: cache hit, replaying logs 2971f8c686b6dec6
@get-bb/plugin-sdk:build:
@get-bb/plugin-sdk:build: > @get-bb/plugin-sdk@0.6.54 build <first-checkout>/packages/plugin-sdk
@get-bb/plugin-sdk:build: > node scripts/build-runtime.mjs
@get-bb/plugin-sdk:build:
@get-bb/plugin-sdk:build: Built 20 @get-bb/plugin-sdk runtime entries.
@get-bb/plugin-sdk:build:types:
@get-bb/plugin-sdk:build:types: > @get-bb/plugin-sdk@0.6.54 build:types <first-checkout>/packages/plugin-sdk
@get-bb/plugin-sdk:build:types: > node scripts/build-bundled-dts.mjs
@get-bb/plugin-sdk:build:types:
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge-testing.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge-acp.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge-acp-next.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-environment-provider.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-machine-provider.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-app.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-host.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-composer-customization-validation.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-composer-handle.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-composer-view.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-file-navigation-validation.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-host-policy.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-plugin-app-collector.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-testing.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-testing-app.d.ts
@get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-testing-host.d.ts
//:ensure-native-modules:
//:ensure-native-modules: > bb@ ensure-native-modules <second-checkout>
//:ensure-native-modules: > node scripts/ensure-native-modules.mjs
//:ensure-native-modules:
@bb/server:test: cache miss, executing e9cd72b928208b15
@bb/server:test:
@bb/server:test: > @bb/server@0.0.1 test <second-checkout>/apps/server
@bb/server:test: > vitest run --config vitest.config.ts "test/services/plugins/plugin-http-disconnect.test.ts"
@bb/server:test:
@bb/server:test:
@bb/server:test: RUN v4.1.1 <second-checkout>/apps/server
@bb/server:test:
@bb/server:test: (node:8571) ExperimentalWarning: SQLite is an experimental feature and might change at any time
@bb/server:test: (Use `node --trace-warnings ...` to show where the warning was created)
@bb/server:test: ❯ |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts (2 tests | 2 failed) 2994ms
@bb/server:test: × aborts the signal and cancels a late response when first accessed before disconnect 1235ms
@bb/server:test: × aborts the signal and cancels a late response when first accessed after disconnect 1153ms
@bb/server:test:
@bb/server:test: ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯
@bb/server:test:
@bb/server:test: FAIL |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts > plugin HTTP disconnect cleanup > aborts the signal and cancels a late response when first accessed before disconnect
@bb/server:test: FAIL |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts > plugin HTTP disconnect cleanup > aborts the signal and cancels a late response when first accessed after disconnect
@bb/server:test: AssertionError: expected { entered: true, returned: true, …(2) } to match object { cancelled: true }
@bb/server:test: (3 matching properties omitted from actual)
@bb/server:test:
@bb/server:test: - Expected
@bb/server:test: + Received
@bb/server:test:
@bb/server:test: {
@bb/server:test: - "cancelled": true,
@bb/server:test: + "cancelled": false,
@bb/server:test: }
@bb/server:test:
@bb/server:test: ❯ test/services/plugins/plugin-http-disconnect.test.ts:96:14
@bb/server:test: 94| await expect
@bb/server:test: 95| .poll(readState, { timeout: 1_000 })
@bb/server:test: 96| .toMatchObject({ cancelled: true });
@bb/server:test: | ^
@bb/server:test: 97| } finally {
@bb/server:test: 98| client.destroy();
@bb/server:test:
@bb/server:test: Caused by: Error: Matcher did not succeed in time.
@bb/server:test: ❯ test/services/plugins/plugin-http-disconnect.test.ts:94:11
@bb/server:test:
@bb/server:test: ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯
@bb/server:test:
@bb/server:test: FAIL |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts > plugin HTTP disconnect cleanup > aborts the signal and cancels a late response when first accessed after disconnect
@bb/server:test: AssertionError: expected { entered: true, returned: true, …(2) } to match object { aborted: true }
@bb/server:test: (3 matching properties omitted from actual)
@bb/server:test:
@bb/server:test: - Expected
@bb/server:test: + Received
@bb/server:test:
@bb/server:test: {
@bb/server:test: - "aborted": true,
@bb/server:test: + "aborted": false,
@bb/server:test: }
@bb/server:test:
@bb/server:test: ❯ test/services/plugins/plugin-http-disconnect.test.ts:93:42
@bb/server:test: 91| await finish();
@bb/server:test: 92| await expect.poll(readState).toMatchObject({ returned: true …
@bb/server:test: 93| expect.soft(await readState()).toMatchObject({ aborted: true…
@bb/server:test: | ^
@bb/server:test: 94| await expect
@bb/server:test: 95| .poll(readState, { timeout: 1_000 })
@bb/server:test:
@bb/server:test: ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯
@bb/server:test:
@bb/server:test:
@bb/server:test: Test Files 1 failed (1)
@bb/server:test: Tests 2 failed (2)
@bb/server:test: Start at 12:14:11
@bb/server:test: Duration 11.42s (transform 4.94s, setup 1.53s, import 4.98s, tests 2.99s, environment 0ms)
@bb/server:test:
@bb/server:test: ELIFECYCLE Test failed. See above for more details.
@bb/server#test: ERROR command (<second-checkout>/apps/server) /usr/local/bin/pnpm run test test/services/plugins/plugin-http-disconnect.test.ts exited (1)
Tasks: 8 successful, 9 total
Cached: 7 cached, 9 total
Time: 13.681s
Failed: @bb/server#test
ERROR run failed: command exited (1)
Fixed regression and existing wire suite: 28 passing tests
• turbo 2.10.12 • Packages in scope: @bb/server • Running test in 1 packages • Remote caching disabled, using shared worktree cache @bb/templates:generate:templates: cache miss, executing 4cfe3aac40aafb15 @bb/templates:generate:plugin-scaffold: cache miss, executing 7dd6488c35f8ec6a @bb/server:generate:bb-official-marketplace: cache miss, executing d518c3f8e38c9ac7 //:ensure-native-modules: cache bypass, force executing 23ee6ae2f06c6f8a @bb/plugin-build:generate: cache miss, executing f2fde3ba316946d1 @bb/templates:generate:templates: @bb/templates:generate:templates: > @bb/templates@0.0.1 generate:templates <first-checkout>/packages/templates @bb/templates:generate:templates: > node ./scripts/generate-templates.mjs @bb/templates:generate:templates: @bb/templates:generate:plugin-scaffold: @bb/templates:generate:plugin-scaffold: > @bb/templates@0.0.1 generate:plugin-scaffold <first-checkout>/packages/templates @bb/templates:generate:plugin-scaffold: > node ./scripts/generate-plugin-scaffold.mjs @bb/templates:generate:plugin-scaffold: @bb/server:generate:bb-official-marketplace: @bb/server:generate:bb-official-marketplace: > @bb/server@0.0.1 generate:bb-official-marketplace <first-checkout>/apps/server @bb/server:generate:bb-official-marketplace: > node --conditions=source --import tsx scripts/generate-bb-official-marketplace.ts @bb/server:generate:bb-official-marketplace: //:ensure-native-modules: //:ensure-native-modules: > bb@ ensure-native-modules <first-checkout> //:ensure-native-modules: > node scripts/ensure-native-modules.mjs //:ensure-native-modules: @bb/plugin-build:generate: @bb/plugin-build:generate: > @bb/plugin-build@0.0.1 generate <first-checkout>/packages/plugin-build @bb/plugin-build:generate: > node ./scripts/generate-plugin-theme.mjs && node ./scripts/generate-runtime-export-manifest.mjs @bb/plugin-build:generate: @bb/plugin-build:generate: plugin-theme.generated.ts up to date @get-bb/plugin-sdk:build: cache miss, executing 863fca7129dc4c2a @get-bb/plugin-sdk:build:types: cache miss, executing b11da95598bfa132 @bb/plugin-build:generate: wrote <first-checkout>/packages/plugin-build/src/generated/runtime-export-manifest.generated.ts (react@19.2.4) @get-bb/plugin-sdk:build: @get-bb/plugin-sdk:build: > @get-bb/plugin-sdk@0.6.54 build <first-checkout>/packages/plugin-sdk @get-bb/plugin-sdk:build: > node scripts/build-runtime.mjs @get-bb/plugin-sdk:build: @get-bb/plugin-sdk:build:types: @get-bb/plugin-sdk:build:types: > @get-bb/plugin-sdk@0.6.54 build:types <first-checkout>/packages/plugin-sdk @get-bb/plugin-sdk:build:types: > node scripts/build-bundled-dts.mjs @get-bb/plugin-sdk:build:types: @bb/agent-runtime:generate:test-bridges: cache miss, executing c3beb2aa96ca287e @bb/agent-runtime:generate:test-bridges: @bb/agent-runtime:generate:test-bridges: > @bb/agent-runtime@0.0.1 generate:test-bridges <first-checkout>/packages/agent-runtime @bb/agent-runtime:generate:test-bridges: > node ./scripts/build-test-bridges.mjs @bb/agent-runtime:generate:test-bridges: @get-bb/plugin-sdk:build: Built 20 @get-bb/plugin-sdk runtime entries. @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge-testing.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge-acp.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-provider-bridge-acp-next.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-environment-provider.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-machine-provider.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-app.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-host.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-composer-customization-validation.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-composer-handle.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-composer-view.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-file-navigation-validation.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-host-policy.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-internal-plugin-app-collector.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-testing.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-testing-app.d.ts @get-bb/plugin-sdk:build:types: Unchanged bundled-types/bb-plugin-sdk-testing-host.d.ts @bb/server:test: cache miss, executing b75209097901c3d5 @bb/server:test: @bb/server:test: > @bb/server@0.0.1 test <first-checkout>/apps/server @bb/server:test: > vitest run --config vitest.config.ts "test/services/plugins/plugin-http-disconnect.test.ts" "test/services/plugins/plugin-wire.test.ts" @bb/server:test: @bb/server:test: @bb/server:test: RUN v4.1.1 <first-checkout>/apps/server @bb/server:test: @bb/server:test: (node:8579) ExperimentalWarning: SQLite is an experimental feature and might change at any time @bb/server:test: (Use `node --trace-warnings ...` to show where the warning was created) @bb/server:test: (node:8578) ExperimentalWarning: SQLite is an experimental feature and might change at any time @bb/server:test: (Use `node --trace-warnings ...` to show where the warning was created) @bb/server:test: ✓ |@bb/server| test/services/plugins/plugin-http-disconnect.test.ts (2 tests) 968ms @bb/server:test: ✓ |@bb/server:isolated| test/services/plugins/plugin-wire.test.ts (26 tests) 4963ms @bb/server:test: ✓ rpc resolves the handler after the body arrives, so a reload during the body read never runs a stale handler 326ms @bb/server:test: ✓ isolates factory and message-handler failures 315ms @bb/server:test: @bb/server:test: Test Files 2 passed (2) @bb/server:test: Tests 28 passed (28) @bb/server:test: Start at 12:14:12 @bb/server:test: Duration 16.32s (transform 13.53s, setup 3.85s, import 13.87s, tests 5.93s, environment 0ms) @bb/server:test: Tasks: 9 successful, 9 total Cached: 0 cached, 9 total Time: 47.834s
Server typecheck
• turbo 2.10.12 • Packages in scope: @bb/server • Running typecheck in 1 packages • Remote caching disabled, using shared worktree cache @bb/templates:generate:plugin-scaffold: cache hit, replaying logs b099233e58b91427 @bb/templates:generate:plugin-scaffold: @bb/templates:generate:plugin-scaffold: > @bb/templates@0.0.1 generate:plugin-scaffold <local-path> @bb/templates:generate:plugin-scaffold: > node ./scripts/generate-plugin-scaffold.mjs @bb/templates:generate:plugin-scaffold: @bb/plugin-build:generate: cache hit, replaying logs 6bff34a2bbad0aaa @bb/plugin-build:generate: @bb/plugin-build:generate: > @bb/plugin-build@0.0.1 generate <local-path> @bb/plugin-build:generate: > node ./scripts/generate-plugin-theme.mjs && node ./scripts/generate-runtime-export-manifest.mjs @bb/plugin-build:generate: @bb/plugin-build:generate: wrote packages/plugin-build/src/generated/plugin-theme.generated.ts @bb/plugin-build:generate: wrote <local-path> (react@19.2.4) @bb/templates:generate:templates: cache hit, replaying logs 20ae257455e4f66d @bb/templates:generate:templates: @bb/templates:generate:templates: > @bb/templates@0.0.1 generate:templates <local-path> @bb/templates:generate:templates: > node ./scripts/generate-templates.mjs @bb/templates:generate:templates: @bb/server:generate:bb-official-marketplace: cache hit, replaying logs 0ef246d98ddb8ddb @bb/server:generate:bb-official-marketplace: @bb/server:generate:bb-official-marketplace: > @bb/server@0.0.1 generate:bb-official-marketplace <local-path> @bb/server:generate:bb-official-marketplace: > node --conditions=source --import tsx scripts/generate-bb-official-marketplace.ts @bb/server:generate:bb-official-marketplace: @bb/server:typecheck: cache miss, executing dd8f9cdbf70b6b5f @bb/server:typecheck: @bb/server:typecheck: > @bb/server@0.0.1 typecheck <first-checkout>/apps/server @bb/server:typecheck: > tsc --noEmit @bb/server:typecheck: Tasks: 5 successful, 5 total Cached: 4 cached, 5 total Time: 5.074s