BloopAI/vibe-kanban · error · ContainerError
Timeout: process took more than 30 seconds to start
Error message
Timeout: process took more than 30 seconds to start
What it means
start_execution_inner wraps executor_action.spawn in a 30-second tokio timeout; if the executor process does not spawn within that window the future is dropped and this timeout error is returned. This prevents hangs from blocked executors (e.g. waiting on network or approval) from stalling executions indefinitely.
Source
Thrown at crates/local-deployment/src/container.rs:1376
drop(config);
let mut env = ExecutionEnv::new(
repo_context,
commit_reminder_enabled,
commit_reminder_prompt,
);
// Always inject workspace/session context
env.insert("VK_WORKSPACE_ID", workspace.id.to_string());
env.insert("VK_WORKSPACE_BRANCH", &workspace.branch);
// Create the child and stream, add to execution tracker with timeout
let mut spawned = tokio::time::timeout(
Duration::from_secs(30),
executor_action.spawn(¤t_dir, approvals_service, &env),
)
.await
.map_err(|_| {
ContainerError::Other(anyhow!(
"Timeout: process took more than 30 seconds to start"
))
})??;
if let Err(e) = self
.track_child_msgs_in_store(execution_process.id, &mut spawned.child)
.await
{
let _ = command::kill_process_group(&mut spawned.child).await;
return Err(e);
}
self.add_child_to_store(execution_process.id, spawned.child)
.await;
// Store cancellation token for graceful shutdown
if let Some(cancel) = spawned.cancel {
self.add_cancellation_token(execution_process.id, cancel)View on GitHub (pinned to 4deb7eca8f)
Solutions
- Retry — transient slowness (network, cold cache) often resolves on a second attempt.
- Pre-install/warm the executor binary so spawn does not need to download it.
- Check network/proxy settings if the executor fetches assets at startup.
- Run the executor command manually in the worktree to see what it is blocking on.
Example fix
// before // spawn hangs 45s on first run downloading the executor // after executors::ensure_executor_installed(&action).await?; // warm cache before spawn let spawned = tokio::time::timeout(Duration::from_secs(30), action.spawn(...)).await??;
Defensive patterns
Strategy: retry
Validate before calling
// ensure the executor binary is available before spawning
if !executor_binary_cached(&action).await? {
executors::install_executor(&action).await?;
} Try / catch
match container.start_execution(...).await {
Err(ContainerError::Other(e)) if e.to_string().contains("Timeout: process took more than 30 seconds") => {
// one retry after warming caches / checking network
warm_executor_cache(&action).await?;
container.start_execution(...).await
}
other => other,
} Prevention
- Pre-install/warm executor binaries before first use.
- Verify network/proxy access for executors that download at startup.
- Avoid executor commands that block on stdin or prompts.
- Time the spawn manually once to know its cold-start cost.
When it happens
Trigger: executor_action.spawn(¤t_dir, approvals_service, &env) taking >30s to return — slow executor binary download/startup, hung credential prompt, filesystem stall, or executor waiting for interactive input.
Common situations: Cold start with no cached executor (large npx/pip fetch), offline or proxied environments blocking downloads, antivirus/permission scans delaying process start, misconfigured executor command that waits on stdin.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Child process has no stdout
- Child process has no stdin
- Cannot run script while another process is running
- Approval has timed out
- Child process not found for execution
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/4a67d2f4eb0f997a.
Report an issue: GitHub.