amir20/dozzle · error
unknown action
Error message
unknown action: %s
What it means
ContainerActions dispatches on a container.Action enum and executes the matching Docker API call. If the action string is not one of the known cases (start, stop, restart, remove, etc.), it falls through to this default error.
Solutions
- Use only the container.Action constants the switch supports (check the full switch in client.go for the current set)
- If you need the missing action, add a case to the switch calling the corresponding client method
- Validate/normalize user-supplied actions against the enum before calling
Example fix
// before
err := client.ContainerActions(ctx, id, "pause")
// after
switch action {
case container.Start, container.Stop, container.Restart, container.Remove:
err = client.ContainerActions(ctx, id, action)
default:
err = fmt.Errorf("unsupported action %q", action)
} Defensive patterns
Strategy: type-guard
Validate before calling
valid := map[container.Action]bool{
container.Start: true, container.Stop: true,
container.Restart: true, container.Remove: true,
}
if !valid[action] {
return fmt.Errorf("unsupported action %q", action)
} Type guard
func isSupportedAction(a container.Action) bool {
switch a {
case container.Start, container.Stop, container.Restart, container.Remove:
return true
}
return false
} Try / catch
if err := client.ContainerActions(ctx, id, action); err != nil {
if strings.HasPrefix(err.Error(), "unknown action") {
return fmt.Errorf("action %q not supported by this client", action)
}
return err
} Prevention
- Only use the container.Action enum constants, never raw strings
- Keep the UI/action enum in sync with the docker client switch
- Add a test covering every enum member against ContainerActions
When it happens
Trigger: Calling ContainerActions with an action value outside the switch, e.g. ContainerActions(ctx, id, "pause") when pause is not implemented, or a typo/empty string for the action.
Common situations: New Docker action added upstream in the UI before the docker client implements it; test code passing an arbitrary string; a caller constructing an action from user input without validating it.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07).
Data as JSON: /api/errors/aae9ec481c799621.
Report an issue: GitHub.
Appendix: source
Thrown at internal/docker/client.go:196
}
func (d *DockerClient) ContainerActions(ctx context.Context, action container.ContainerAction, containerID string) error {
switch action {
case container.Start:
_, err := d.cli.ContainerStart(ctx, containerID, client.ContainerStartOptions{})
return err
case container.Stop:
_, err := d.cli.ContainerStop(ctx, containerID, client.ContainerStopOptions{})
return err
case container.Restart:
_, err := d.cli.ContainerRestart(ctx, containerID, client.ContainerRestartOptions{})
return err
case container.Remove:
_, err := d.cli.ContainerRemove(ctx, containerID, client.ContainerRemoveOptions{})
return err
default:
return fmt.Errorf("unknown action: %s", action)
}
}
func (d *DockerClient) ImagePull(ctx context.Context, imageName string) (io.ReadCloser, error) {
return d.cli.ImagePull(ctx, imageName, client.ImagePullOptions{})
}
// ImageRepoDigests returns the "repo@sha256:..." digests recorded for a
// locally available image. An image built locally has none, which is what
// makes it impossible to check for updates. The repository is kept because an
// image can carry digests for several repositories, and only the one being
// checked is comparable.
func (d *DockerClient) ImageRepoDigests(ctx context.Context, imageID string) ([]string, error) {
result, err := d.cli.ImageInspect(ctx, imageID)
if err != nil {
return nil, err
}
View on GitHub (pinned to d9463cbe21)