fix(cli/run): add retry mechanism for session creation

The OpenCode server may not be fully initialized even after
reporting 'listening'. Add retry with exponential backoff (3 attempts)
and proper error handling to make session creation more robust.

This fixes CI failures where session.create() fails immediately
after server startup.

Fixes #935 (CI failure)
This commit is contained in:
justsisyphus
2026-01-20 14:37:10 +09:00
parent 8f94c59892
commit 6a4add2011

View File

@@ -6,6 +6,8 @@ import { createEventState, processEvents, serializeError } from "./events"
const POLL_INTERVAL_MS = 500
const DEFAULT_TIMEOUT_MS = 0
const SESSION_CREATE_MAX_RETRIES = 3
const SESSION_CREATE_RETRY_DELAY_MS = 1000
export async function run(options: RunOptions): Promise<number> {
const {
@@ -45,13 +47,49 @@ export async function run(options: RunOptions): Promise<number> {
})
try {
const sessionRes = await client.session.create({
body: { title: "oh-my-opencode run" },
})
// Retry session creation with exponential backoff
// Server might not be fully ready even after "listening" message
let sessionID: string | undefined
let lastError: unknown
for (let attempt = 1; attempt <= SESSION_CREATE_MAX_RETRIES; attempt++) {
const sessionRes = await client.session.create({
body: { title: "oh-my-opencode run" },
})
if (sessionRes.error) {
lastError = sessionRes.error
console.error(pc.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES} failed:`))
console.error(pc.dim(` Error: ${serializeError(sessionRes.error)}`))
if (attempt < SESSION_CREATE_MAX_RETRIES) {
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt
console.log(pc.dim(` Retrying in ${delay}ms...`))
await new Promise((resolve) => setTimeout(resolve, delay))
continue
}
}
sessionID = sessionRes.data?.id
if (sessionID) {
break
}
// No error but also no session ID - unexpected response
lastError = new Error(`Unexpected response: ${JSON.stringify(sessionRes, null, 2)}`)
console.error(pc.yellow(`Session create attempt ${attempt}/${SESSION_CREATE_MAX_RETRIES}: No session ID returned`))
if (attempt < SESSION_CREATE_MAX_RETRIES) {
const delay = SESSION_CREATE_RETRY_DELAY_MS * attempt
console.log(pc.dim(` Retrying in ${delay}ms...`))
await new Promise((resolve) => setTimeout(resolve, delay))
}
}
const sessionID = sessionRes.data?.id
if (!sessionID) {
console.error(pc.red("Failed to create session"))
console.error(pc.red("Failed to create session after all retries"))
console.error(pc.dim(`Last error: ${serializeError(lastError)}`))
cleanup()
return 1
}