vxcontrol/pentagi · error

failed to attach to exec process

Error message

failed to attach to exec process: %w

What it means

This error is returned by getExecResult when the Docker API call ContainerExecAttach fails, meaning the library could not attach a TTY stream to the already-created exec instance inside the container. Attaching is required to capture the command's output, so without it the result cannot be read.

Solutions

  1. Verify the target container is running before executing (docker ps / IsContainerRunning)
  2. Check Docker daemon health and socket permissions (docker info; user in docker group)
  3. Retry the command — attach races are often transient
  4. Confirm the Docker client library and daemon API versions are compatible

Example fix

// before
out, err := term.ExecCommand(ctx, flowID, cmd, false) // container was just restarted
// after
if ok, _ := docker.IsContainerRunning(ctx, containerLID); !ok {
    return errors.New("container not running; start it before ExecCommand")
}
out, err := term.ExecCommand(ctx, flowID, cmd, false)
Defensive patterns

Strategy: retry

Validate before calling

if ok, err := docker.IsContainerRunning(ctx, containerLID); err != nil || !ok {
    return fmt.Errorf("container not ready before exec: running=%v err=%v", ok, err)
}

Try / catch

out, err := term.ExecCommand(ctx, flowID, cmd, false)
if err != nil && strings.Contains(err.Error(), "failed to attach to exec process") {
    time.Sleep(500 * time.Millisecond)
    out, err = term.ExecCommand(ctx, flowID, cmd, false) // single retry
}

Prevention

When it happens

Trigger: ExecCommand → getExecResult calls t.dockerClient.ContainerExecAttach(ctx, id, ExecAttachOptions{TTY:true}) and the Docker daemon returns an error: exec instance was removed, container stopped between create and attach, daemon connection lost, or the exec ID is invalid.

Common situations: Container stopped/restarted mid-command; Docker daemon outage or socket permission issues; race where the exec completes and is reaped before attach; Docker API version mismatches.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/84c60062f2185ba6. Report an issue: GitHub.

Appendix: source

Thrown at backend/pkg/tools/terminal.go:273

			return fmt.Sprintf("Command started in background with timeout %s (still running)", timeout), nil
		}
	}

	return t.getExecResult(ctx, createResp.ID, timeout)
}

func (t *terminal) getExecResult(ctx context.Context, id string, timeout time.Duration) (string, error) {
	if timeout > 0 {
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, timeout)
		defer cancel()
	}

	resp, err := t.dockerClient.ContainerExecAttach(ctx, id, client.ExecAttachOptions{
		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

View on GitHub (pinned to ea665308ba)