Fix OAuth callback port flake (#9841)

* fix(cli): avoid OAuth callback port bind without redirect

* fix(cli): clean up failed OAuth callback binding
This commit is contained in:
Marius
2026-05-04 16:06:54 +02:00
committed by GitHub
parent 614bca7cff
commit fc2545ceb4
2 changed files with 66 additions and 4 deletions
@@ -1,5 +1,6 @@
import { test, expect, mock, beforeEach } from "bun:test"
import { Effect } from "effect"
import { createServer } from "http" // kilocode_change
// Mock UnauthorizedError to match the SDK's class
class MockUnauthorizedError extends Error {
@@ -109,10 +110,40 @@ beforeEach(() => {
connectSucceedsImmediately = false
})
// kilocode_change start
async function occupy(port: number) {
const srv = createServer()
const bound = await new Promise<boolean>((resolve, reject) => {
const fail = (err: Error & { code?: string }) => {
srv.off("error", fail)
if (err.code === "EADDRINUSE") {
resolve(false)
return
}
reject(err)
}
srv.once("error", fail)
srv.listen(port, "127.0.0.1", () => {
srv.off("error", fail)
resolve(true)
})
})
return {
async [Symbol.asyncDispose]() {
if (!bound) return
await new Promise<void>((resolve) => srv.close(() => resolve()))
},
}
}
// kilocode_change end
// Import modules after mocking
const { MCP } = await import("../../src/mcp/index")
const { Instance } = await import("../../src/project/instance")
const { tmpdir } = await import("../fixture/fixture")
const { OAUTH_CALLBACK_PORT } = await import("../../src/mcp/oauth-provider") // kilocode_change
test("first connect to OAuth server shows needs_auth instead of failed", async () => {
await using tmp = await tmpdir({
@@ -251,6 +282,10 @@ test("authenticate() stores a connected client when auth completes without redir
)
},
})
// kilocode_change start
await using port = await occupy(OAUTH_CALLBACK_PORT)
void port
// kilocode_change end
await Instance.provide({
directory: tmp.path,