stablyai/orca · error · Error

Timed out polling ${label} after ${pollTimeoutMs}ms.

Error message

Timed out polling ${label} after ${pollTimeoutMs}ms.

What it means

pollWithTimeout races a single read against pollTimeoutMs (2500ms) and throws 'Timed out polling {label} after 2500ms.' when it does not settle. Each poll in the terminal exercise gets its own short deadline instead of relying solely on waitFor's loop, because an unfixed Wayland GPU stall can freeze a single renderer protocol call indefinitely.

Source

Thrown at config/scripts/linux-wayland-terminal-exercise.mjs:46

    if (char === '\\r' || char === '\\n') continue
    seq += 1
    process.stdout.write('WAYLAND_TYPED_${runId}_' + seq + ':' + char + '\\n')
  }
})
`
}

async function pollWithTimeout(label, read) {
  const readPromise = Promise.resolve().then(read)
  readPromise.catch(() => undefined)
  // Why: the unfixed Wayland GPU stall can freeze renderer protocol calls, so
  // each poll needs its own deadline instead of relying only on waitFor's loop.
  const result = await Promise.race([
    readPromise.then((value) => ({ timedOut: false, value })),
    delay(pollTimeoutMs).then(() => ({ timedOut: true, value: null }))
  ])
  if (result.timedOut) {
    throw new Error(`Timed out polling ${label} after ${pollTimeoutMs}ms.`)
  }
  return result.value
}

async function waitFor(label, read, timeout = terminalWaitTimeoutMs) {
  const startedAt = Date.now()
  let lastValue
  while (Date.now() - startedAt < timeout) {
    lastValue = await pollWithTimeout(label, read)
    if (lastValue) {
      return lastValue
    }
    await delay(50)
  }
  throw new Error(`Timed out waiting for ${label}; last value: ${JSON.stringify(lastValue)}`)
}

async function getTerminalContent(page, charLimit = 12_000) {

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Read the label in the message to identify which read wedged, then check earlier phase logs.
  2. Investigate the GPU stall root cause — the per-poll timeout is a detector, not the fix.
  3. If a read is genuinely slow (not wedged), the underlying waitFor timeout (45s) is the larger budget.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  value = await pollWithTimeout(label, read)
} catch (err) {
  if (/Timed out polling/.test(err.message)) log.warn(`GPU wedge suspected at '${label}'`)
  throw err
}

Prevention

When it happens

Trigger: A page.evaluate read inside waitFor (store exposure, hydration, PTY binding, scrollback marker, typed marker) hangs past 2500ms due to a GPU wedge.

Common situations: Wayland GPU process wedged during terminal exercise in CI; renderer frozen mid-protocol.

Understand the failure class

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/eeec6d995a4317b4. Report an issue: GitHub.