amir20/dozzle · error

update failed

Error message

update failed: %w

What it means

executeUpdateContainer runs the update (pull latest image + recreate) asynchronously and drains a progress channel; when the update goroutine reports an error it is wrapped as "update failed". This means argument parsing and container lookup succeeded, but the actual Docker update operation errored.

Solutions

  1. Inspect the wrapped error (%w) for the root cause (pull vs stop vs recreate) and address it directly.
  2. Verify registry access: `docker pull <image>` on the host; add registry credentials if authentication is the cause.
  3. Ensure no external orchestrator (compose restart policy, swarm service) will recreate/conflict with the container during update.
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-checks: registry reachable and image pullable
const pull = await runOnHost(host, `docker pull ${image}`);
if (pull.code !== 0) throw new Error("image pull would fail: " + pull.stderr);

Try / catch

try {
  return await callTool("update_container", argsJSON);
} catch (e) {
  if (String(e).includes("update failed")) {
    // inspect wrapped cause: pull vs stop vs recreate; fix root cause, do not blind-retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Image pull failure (registry unreachable, auth required), container cannot be stopped/recreated (dependency, volume, or network conflicts), Docker daemon errors during recreate, or the update implementation rejects the operation.

Common situations: Private registry without credentials on the host; no network access to the registry from the Docker host; container managed by compose/swarm fighting the manual recreate; port already bound by another container after recreation.

Related errors


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/03498ef305661c6f. Report an issue: GitHub.

Appendix: source

Thrown at internal/cloud/tools_actions.go:83

	cs, err := deps.HostService.FindContainer(hostID, containerID, deps.Labels)
	if err != nil {
		return nil, fmt.Errorf("container not found: %w", err)
	}

	progressCh := make(chan container.UpdateProgress)
	var updated bool
	var updateErr error
	done := make(chan struct{})
	go func() {
		updated, updateErr = cs.Update(ctx, progressCh)
		close(done)
	}()
	for range progressCh {
	}
	<-done
	if updateErr != nil {
		return nil, fmt.Errorf("update failed: %w", updateErr)
	}

	message := fmt.Sprintf("Successfully updated container %s by pulling the latest image and recreating it.", cs.Container.Name)
	if !updated {
		message = fmt.Sprintf("Container %s is already running the latest image. No update was needed.", cs.Container.Name)
	}

	return &pb.CallToolResponse{
		Success: true,
		Result: &pb.CallToolResponse_Action{Action: &pb.ActionResult{
			Success:     true,
			ContainerId: cs.Container.ID,
			Action:      "update",
			Message:     message,
		}},
	}, nil
}

View on GitHub (pinned to d9463cbe21)