vxcontrol/pentagi · error

container inspection failed: %w

Error message

container inspection failed: %w

What it means

IsContainerRunning inspects the container to read its state; a non-NotFound inspect error is wrapped with this message. NotFound is deliberately treated as 'not running' with no error, so this error always means a real daemon/communication failure.

Source

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

				case database.ContainerStatusStarting, database.ContainerStatusRunning:
					wg.Add(1)
					go removeContainer(container.LocalID.String, container.ID)
				}
			}
		}
	}

	wg.Wait()
	logger.Info("cleanup finished")

	return nil
}

func (dc *dockerClient) IsContainerRunning(ctx context.Context, containerID string) (bool, error) {
	inspectResult, err := dc.client.ContainerInspect(ctx, containerID, client.ContainerInspectOptions{})
	if err != nil {
		if !cerrdefs.IsNotFound(err) {
			return false, fmt.Errorf("container inspection failed: %w", err)
		}
		// a removed container is missing, not an inspection failure
		return false, nil
	}

	inspection := inspectResult.Container
	if inspection.State == nil {
		// the daemon always populates State for a successfully inspected
		// container; treat the unexpected absence as "not running" rather
		// than panicking on the field access below.
		return false, nil
	}

	// Check both Running state and health status if available
	isOperational := inspection.State.Running
	if inspection.State.Health != nil && inspection.State.Health.Status != "" {
		isOperational = isOperational && inspection.State.Health.Status != "unhealthy"
	}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check daemon reachability with `docker info` / `docker ps` from the backend environment
  2. Validate the containerID is a proper 64-hex ID or valid name (strip whitespace/ANSI from tool output before calling)
  3. Verify Docker socket permissions and DOCKER_HOST configuration
  4. Confirm SDK and daemon API versions are compatible after upgrades

Example fix

// before
id := strings.TrimSpace(toolOutput)
running, err := dc.IsContainerRunning(ctx, id)
// after
id := strings.TrimSpace(toolOutput)
if id == "" || !validContainerIDRe.MatchString(id) {
    return false, fmt.Errorf("invalid container id %q", id)
}
running, err := dc.IsContainerRunning(ctx, id)
Defensive patterns

Strategy: validation

Validate before calling

var validContainerIDRe = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$`)
func validContainerID(id string) bool {
    return validContainerIDRe.MatchString(strings.TrimSpace(id))
}

Type guard

func isInspectable(err error) bool { return !cerrdefs.IsNotFound(err) }

Try / catch

running, err := dc.IsContainerRunning(ctx, id)
if err != nil {
    // daemon-level failure, not 'container missing'
    log.WithError(err).Error("cannot determine container state")
    return err
}

Prevention

When it happens

Trigger: dc.client.ContainerInspect returns a non-NotFound error: Docker daemon unreachable or restarting, malformed containerID, permission denied on the Docker socket, or an API version mismatch between the SDK and dockerd.

Common situations: Docker daemon restart mid-flow; backend container missing access to /var/docker.sock; DOCKER_HOST pointing at a dead TCP endpoint; SDK/daemon API version skew after a Docker upgrade; containerID containing invalid characters (e.g. a name with a newline from tool output).

Related errors


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