xai-org/grok-build · error
agent runtime worker join: {e}
Error message
agent runtime worker join: {e} What it means
The spawn_blocking task that builds the dedicated tokio current-thread runtime for the ACP agent worker was joined with a JoinError — the blocking task panicked or was cancelled before producing a runtime. spawn_agent_thread_direct maps that to this error so spawn fails cleanly instead of starting ACP in a broken state.
Source
Thrown at crates/codegen/xai-grok-pager/src/acp/spawn.rs:270
}
/// Spawn an agent in a dedicated thread with direct RPC dispatch.
///
/// The agent runs on a single-threaded tokio LocalSet runtime.
/// RPC requests go directly to the agent via Rc, bypassing simplex pipes.
async fn spawn_agent_thread_direct(
spawn_agent: Box<dyn FnOnce(AcpClientTx) -> Result<Rc<MvpAgent>> + Send + 'static>,
channel: AcpAgentChannel,
cancel: CancellationToken,
skills_paths: Vec<String>,
) -> Result<thread::JoinHandle<Result<()>>> {
// Off the UI worker: failure must fail spawn, not start ACP.
let rt = tokio::task::spawn_blocking(|| {
let mut builder = tokio::runtime::Builder::new_current_thread();
xai_tty_utils::runtime::build_with_blocking_pool(builder.enable_all())
})
.await
.map_err(|e| anyhow::anyhow!("agent runtime worker join: {e}"))?
.map_err(|e| {
tracing::error!(error = %e, "failed to start agent runtime");
anyhow::anyhow!("failed to start agent runtime: {e}")
})?;
Ok(thread::Builder::new()
.name("acp-agent-worker".into())
.spawn(move || -> Result<()> {
let local = tokio::task::LocalSet::new();
local.block_on(&rt, async move {
let client_tx = channel.tx.clone();
let agent_rc = spawn_agent(client_tx)?;
// Direct dispatch: RPC requests go straight to the agent
let gw_rx =
AcpGatewayReceiver::new(channel.rx, agent_rc.clone()).with_tracing(true);
tokio::task::spawn_local(gw_rx.run());
let _skills_watcher = {View on GitHub (pinned to bc7f02eddd)
Solutions
- Inspect logs for a panic in the runtime-builder task (JoinError payload)
- Check thread/memory limits (ulimit -u, cgroup limits) that could kill worker threads
- Retry spawn; if it recurs during shutdown, avoid racing spawn_agent_thread_direct with process teardown
- Report/investigate build_with_blocking_pool panics in xai_tty_utils
Defensive patterns
Strategy: retry
Try / catch
match spawn_grok_shell(opts).await {
Err(e) if e.to_string().contains("agent runtime worker join") => {
// JoinError: panic or cancellation; check panic payload in logs, retry once
retry_spawn(opts, 1).await
}
r => r,
} Prevention
- Avoid racing spawn with process shutdown/cancellation
- Monitor system thread limits before launching many agents
- Capture JoinError panic payloads in logs for diagnosis
- Keep xai_tty_utils runtime builder configuration valid and tested
When it happens
Trigger: Calling spawn_agent_thread_direct (via spawn_grok_shell) when the spawn_blocking closure panics (e.g. build_with_blocking_pool fails/panics) or the blocking-pool task is cancelled.
Common situations: Runtime construction panicking under resource exhaustion (thread limits, memory), cancellation during shutdown racing spawn, bugs in blocking-pool configuration.
Related errors
- failed to start agent runtime: {e}
- Task panicked: {}
- blocking pre-allocate task panicked: {e}
- blocking write task panicked: {e}
- decode task panicked: {e}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/9767ed7d87ef2deb.
Report an issue: GitHub.