vxcontrol/pentagi · warning
stop timed out after %s — the task may still be winding down
Error message
stop timed out after %s — the task may still be winding down. Call %s to check the current state before proceeding
What it means
The stop handler was given a bounded context (flowOperationTimeout) and returned context.DeadlineExceeded or context.Canceled, so stop_flow could not confirm the flow stopped within the operation window. The message is deliberately advisory: the stop may still complete asynchronously, and the caller is told to re-check with get_flow_status.
Source
Thrown at backend/pkg/tools/flow_manager.go:645
isRunning := false
for _, task := range tasks {
if task.Status == database.TaskStatusRunning {
isRunning = true
break
}
}
if !isRunning {
return "No running task found — the flow is already in 'waiting' state and ready to accept input.", nil
}
stopCtx, stopCancel := context.WithTimeout(ctx, flowOperationTimeout)
defer stopCancel()
if err := t.handler(stopCtx, action.Reason); err != nil {
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
return "", fmt.Errorf(
"stop timed out after %s — the task may still be winding down. "+
"Call %s to check the current state before proceeding",
flowOperationTimeout, GetFlowStatusToolName)
}
return "", fmt.Errorf("failed to stop flow: %w", err)
}
// Re-query task statuses to report the actual state the flow reached.
newTasks, err := t.db.GetFlowTasks(ctx, t.flowID)
if err != nil {
// Stop succeeded but we cannot verify the new state — return a safe partial message.
return fmt.Sprintf(
"Flow stop initiated (reason: %s). Could not verify new status: %s. "+
"Call %s to confirm before proceeding.",
action.Reason, err, GetFlowStatusToolName), nil
}
for _, task := range newTasks {View on GitHub (pinned to ea665308ba)
Solutions
- Call get_flow_status to check whether the flow actually stopped; it may have finished after the timeout.
- Wait a few seconds and call stop_flow again if it is still running.
- Check for long-running containers/commands in the flow's sandbox and terminate them if the flow refuses to wind down.
- Inspect backend logs to see whether the stop handler completed after the deadline.
Example fix
// after a stop timeout, verify before retrying
const status = await getFlowStatus(flowId);
if (status === 'running') {
await stopFlow(flowId, 'retry stop');
} Defensive patterns
Strategy: fallback
Try / catch
try {
await tool.call('stop_flow', { reason: 'stop requested' });
} catch (err) {
if (String(err).includes('stop timed out')) {
// stop may complete async: verify, then retry if still running
const status = await tool.call('get_flow_status', { detail: 'running' });
if (stillRunning(status)) await tool.call('stop_flow', { reason: 'retry stop' });
}
} Prevention
- Always re-check with get_flow_status after a stop timeout
- Allow graceful wind-down: wait before retrying stop
- Avoid launching very long commands that ignore cancellation
- Monitor backend logs for slow shutdown paths
When it happens
Trigger: Calling stop_flow when the underlying flow shutdown takes longer than flowOperationTimeout (graceful in-flight tool execution finishing), or the handler's context is cancelled externally during the stop.
Common situations: Stopping a flow whose executor is mid-command in a Docker sandbox; long-running terminal commands that ignore cancellation; heavily loaded backend slowing the shutdown path.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- listing container directory '%s': %w
- image download stream processing failed: %w
- wait cancelled — the assistant session was interrupted while
- command execution timeout (%v). Partial output: %s. HINT: If
- Internal
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/ad680264a8e7e63e.
Report an issue: GitHub.