vxcontrol/pentagi · error

failed to stop container: %w

Error message

failed to stop container: %w

What it means

Wraps a failure from StopContainer during RemoveContainer (backend/pkg/docker/client.go). A container cannot be removed until it is stopped, so any stop failure (Docker daemon error, context cancellation, already-waiting container) aborts removal with this error. The database status is left unchanged.

Source

Thrown at backend/pkg/docker/client.go:756

	_, err := dc.db.UpdateContainerStatus(ctx, database.UpdateContainerStatusParams{
		Status: database.ContainerStatusStopped,
		ID:     dbID,
	})
	if err != nil {
		return fmt.Errorf("database status update failed during container stop: %w", err)
	}

	logger.Info("container shutdown completed successfully")

	return nil
}

func (dc *dockerClient) RemoveContainer(ctx context.Context, containerID string, dbID int64) error {
	logger := dc.logger.WithContext(ctx).WithField("local_id", containerID)
	logger.Info("removing container and associated resources")

	if err := dc.StopContainer(ctx, containerID, dbID); err != nil {
		return fmt.Errorf("failed to stop container: %w", err)
	}

	options := client.ContainerRemoveOptions{
		RemoveVolumes: true,
		Force:         true,
	}
	if _, err := dc.client.ContainerRemove(ctx, containerID, options); err != nil {
		if !cerrdefs.IsNotFound(err) {
			return fmt.Errorf("failed to remove container: %w", err)
		}
		// already gone (removed manually, or a prior call already succeeded);
		// still mark it deleted below so the database row does not go stale.
		logger.WithError(err).Warn("container not found")
	}

	_, err := dc.db.UpdateContainerStatus(ctx, database.UpdateContainerStatusParams{
		Status: database.ContainerStatusDeleted,
		ID:     dbID,

View on GitHub (pinned to ea665308ba)

Solutions

  1. Read the wrapped cause (%w chain) to determine whether it was the Docker stop or the DB update that failed
  2. If the container is already gone (NotFound inside StopContainer), it is safe to proceed — RemoveContainer tolerates missing containers during remove
  3. Force-remove directly with ContainerRemoveOptions{Force:true} if stop keeps failing
  4. Check daemon and database health before retrying the removal
Defensive patterns

Strategy: try-catch

Validate before calling

// verify container exists and is stoppable before removal
inspect, err := dockerCli.ContainerInspect(ctx, id)
if err != nil && cerrdefs.IsNotFound(err) {
    return nil // nothing to remove
}

Type guard

func isTeardownBlocked(err error) bool {
    return strings.Contains(err.Error(), "failed to stop container")
}

Try / catch

if err := dc.RemoveContainer(ctx, id, dbID); err != nil {
    log.WithError(err).Error("container teardown failed")
    // schedule re-clean: mark row stale and retry later
}

Prevention

When it happens

Trigger: dc.StopContainer returns an error — either the Docker stop call failed (error 270) or the subsequent DB status update failed (error 271); RemoveContainer propagates it wrapped.

Common situations: Daemon unreachable during flow cleanup; paused/dead container that cannot be stopped; Postgres outage while marking the container stopped; race between two teardown paths on the same container.

Related errors


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