vxcontrol/pentagi · error
failed to copy output: %w
Error message
failed to copy output: %w
What it means
getExecResult copies the exec stream into a buffer with io.Copy; this error wraps any copy failure other than io.EOF. It means the stdout/stderr stream from the exec process was interrupted abnormally before the command's output was fully read.
Source
Thrown at backend/pkg/tools/terminal.go:288
TTY: true,
})
if err != nil {
return "", fmt.Errorf("failed to attach to exec process: %w", err)
}
defer resp.Close()
dst := bytes.Buffer{}
errChan := make(chan error, 1)
go func() {
_, copyErr := io.Copy(&dst, resp.Reader)
errChan <- copyErr
}()
select {
case err := <-errChan:
if err != nil && err != io.EOF {
return "", fmt.Errorf("failed to copy output: %w", err)
}
case <-ctx.Done():
// Close the response to unblock io.Copy
resp.Close()
// Wait for the copy goroutine to finish
<-errChan
suggestedTimeout := max(int(timeout.Seconds())-10, 10)
return "", fmt.Errorf(
"command execution timeout (%v). Partial output: %s. "+
"HINT: If this is an interactive command (shell/REPL/listener), use detach=true. "+
"For long batch commands, wrap with shell timeout utility: 'timeout %d <command>' to ensure clean completion",
ctx.Err(),
truncateString(dst.String(), 500),
suggestedTimeout,
)
}View on GitHub (pinned to ea665308ba)
Solutions
- Retry the command — transient stream resets are common
- Check container health and logs (docker logs) for crashes during execution
- Verify Docker daemon connectivity (especially for remote/TLS endpoints)
- If the command hangs, the timeout path (943) will fire instead; ensure the command terminates
Example fix
// before
out, err := term.ExecCommand(ctx, flowID, cmd, false) // stream died midway
// after
var out string
for attempt := 1; attempt <= 3; attempt++ {
out, err = term.ExecCommand(ctx, flowID, cmd, false)
if err == nil || !strings.Contains(err.Error(), "failed to copy output") {
break
}
time.Sleep(time.Second * time.Duration(attempt))
} Defensive patterns
Strategy: retry
Type guard
func isCopyOutputErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to copy output")
} Try / catch
out, err := term.ExecCommand(ctx, flowID, cmd, false)
if isCopyOutputErr(err) {
// transient stream reset — retry with backoff
time.Sleep(time.Second)
out, err = term.ExecCommand(ctx, flowID, cmd, false)
} Prevention
- Retry once or twice — stream resets are frequently transient
- Keep the Docker client and daemon on a stable, low-latency connection
- Watch for container OOM/kills during long commands (docker events)
- For remote daemons, ensure keepalives and sane TLS timeouts
When it happens
Trigger: The goroutine running io.Copy(resp.Reader, &dst) sends a non-EOF error to errChan: the Docker connection dropped mid-stream, the hijacked connection was reset, or the exec process died in a way that broke the stream.
Common situations: Network interruption between client and Docker daemon; container killed/crashed while the command was streaming output; daemon restart; TLS/connection timeouts on remote Docker hosts.
Related errors
- truncated exec stream: %w
- image download stream processing failed: %w
- failed to read file-check output: %w
- failed to ensure docker network %s: %w
- failed to pull default image '%s': %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/b0a164d5255ad266.
Report an issue: GitHub.