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