bug: logical refresh fails with 'failed to inspect image' for images not yet cached locally
## Summary After updating the configured `databaseContainer.dockerImage` (or any of the `logicalDump`/`logicalRestore`/`logicalSnapshot.dataPatching` images) to a tag that is **not yet present in the local Docker cache**, every retrieval refresh fails immediately with: ``` failed to refresh data: failed to scan pulling image response: failed to inspect image "postgresai/extended-postgres:16-0.5.3": Error response from daemon: No such image: postgresai/extended-postgres:16-0.5.3 ``` The same configuration works as soon as the image is manually pre-pulled with `docker pull` on the host. The bug is purely in DBLab's image-pull helper — the registry, the network, and the daemon are all healthy. ## Repro 1. Fresh DBLab instance running master (i.e. anything built after MR !1129 / commit `9603f326 chore(deps): batch patch-level go and ui dependency bumps`). 2. Open the UI Configuration tab and change `databaseContainer.dockerImage` to any valid published tag that has not yet been pulled on the host (e.g. `postgresai/extended-postgres:16-0.5.3` if the host only has `:15`). 3. Save the config. The config-update handler at `internal/srv/config.go:93` removes the pending marker and fires `s.Retrieval.FullRefresh(ctx)` in a goroutine. The dump job calls `tools.PullImage`, which fails as above. Retrieval moves to `refresh_failed` and the UI surfaces the same string. Workaround: SSH to the host and run `docker pull <image>` manually, then re-trigger the refresh — DBLab's cache check now short-circuits before hitting the buggy code path. ## Root cause `engine/internal/retrieval/engine/postgres/tools/tools.go:522` (`tools.PullImage`) does an inspect-first cache check: ```go inspectionResult, err := dockerClient.ImageInspect(ctx, image) if err != nil { if _, ok := err.(errdefs.ErrNotFound); !ok { return errors.Wrapf(err, \"failed to inspect image %q\", image) } } ``` `errdefs.ErrNotFound` is an interface (`type ErrNotFound interface { NotFound() }`). The Go type assertion `err.(errdefs.ErrNotFound)` only matches if `err`'s **dynamic type directly satisfies** the interface — it does **not** unwrap via `errors.As`/`errors.Is`. In Docker SDK **v23** (used by DBLab until very recently), `ImageInspect` returned a bare value whose type satisfied the assertion, so the code worked. In Docker SDK **v28** (pulled in by `9603f326`), the daemon's HTTP 404 response is wrapped before reaching the call site, so the assertion silently returns `ok == false`. The code then misclassifies \"image not yet pulled\" as a fatal inspect failure and **never attempts the pull**. The 'failed to scan pulling image response' wrapper at `engine/internal/retrieval/engine/postgres/logical/dump.go:289` is dead text from a former JSON-decode loop in `PullImage` that no longer exists, which makes the user-visible message extra-misleading. There is a related, latent issue in the same function: the JSON-stream error from `jsonmessage.DisplayJSONMessagesToStream` is currently logged and discarded (`return nil`) instead of being propagated. With the type-assertion bug fixed but the stream-error path left as-is, errors that surface only in the pull stream body (manifest unknown, auth failure, partial-download failures, etc.) would still be silently swallowed, so it should be fixed in the same MR. ## Affected versions - master (since `9603f326`, ~1 day ago) - Any unreleased build that includes the `9603f326` Docker SDK bump - The currently published `postgresai/dblab-server:4.0.4` is **not** affected (still on the older SDK) ## Suggested fix 1. Replace the type assertion with `errdefs.IsNotFound(err)` (or, preferably, `containerd/errdefs.IsNotFound`, since `docker/errdefs.IsNotFound` is now a deprecated alias). Both walk the error chain via `errors.Is`. 2. Propagate the JSON-stream error from `jsonmessage.DisplayJSONMessagesToStream` instead of logging-and-returning-nil, so registry/auth/manifest errors surface to the caller. 3. Drop the misleading `failed to scan pulling image response` wrapper text in `dump.go` and `runci/handlers.go` and replace with something that describes what the calling code is actually doing (e.g. `failed to prepare dump image`). 4. Add unit tests for `tools.PullImage` covering: cache hit, plain not-found triggers pull, **wrapped** not-found triggers pull (the regression guard for this bug), non-not-found inspect error propagation, and pull-stream error propagation.
issue