Skip to content

Surface Incus stderr in error messages from IncusOutput wrapper #276

@mensfeld

Description

@mensfeld

Problem

container.IncusOutput() captures stdout but discards stderr. When the underlying incus command fails, callers only see exit status N instead of the actual error message from Incus. This makes debugging coi container info, coi container list, coi image info, etc. harder than necessary.

Example:
```
$ coi container info nonexistent
Error: failed to get container info: exit status 1
```

Expected:
```
$ coi container info nonexistent
Error: failed to get container info: exit status 1: Error: Instance not found
```

Context

Raised by Copilot during PR #274 review on the new container info / image info commands. Not addressed in that PR because:

  1. The suggested IncusOutputWithStderr helper does not exist in the codebase
  2. Fixing only the two new commands would introduce inconsistency — container list, image list, and other callers have the same problem
  3. A uniform fix requires adding a new helper and migrating all call sites, which is out of scope for a CLI consistency PR

Proposed approach

  1. Add a new helper in `internal/container/` (e.g. `IncusOutputWithStderr`) that captures both stdout and stderr from `incus` commands
  2. On error, include the trimmed stderr in the returned error so callers can wrap it with context
  3. Migrate all `IncusOutput` call sites to the new helper — or change `IncusOutput` itself if no callers rely on the current stderr-silencing behavior
  4. Callers should format errors like:
    ```go
    if err != nil {
    if stderr := strings.TrimSpace(stderrOutput); stderr != "" {
    return fmt.Errorf("failed to X: %v: %s", err, stderr)
    }
    return fmt.Errorf("failed to X: %v", err)
    }
    ```

Affected call sites

At minimum:

  • `internal/cli/container.go` — `container info`, `container list`
  • `internal/cli/images.go` — `image info`
  • Any other callers of `container.IncusOutput` in the codebase

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions