vscode-container-client: support the wslc 2.9.8+ JSON output formats - #604
Merged
Brandon Waterloo [MSFT] (bwateratmsft) merged 3 commits intoSep 2, 2026
Merged
Conversation
wslc 2.9.8 replaced the service's native `--format json` records with Docker-compatible, all-string ones. `images` went from `Id` / epoch-seconds `Created` / byte-count `Size` to `ID` / `CreatedAt` date string / human-readable `Size`, and `network list` went from the inspect-style shape to Docker's flat `network ls` shape. The schemas only knew the old shapes, so every record failed Zod validation and the Images view reported a connection failure. Accept both wslc generations via unions rather than switching formats outright, so the extension keeps working against 2.9.3/2.9.4 as well. The two shapes are disjoint (`ID`/`CreatedAt` vs `Id`/`Created`), so records belonging to neither are still rejected instead of silently parsing as empty. Also pass `--no-trunc` to `images`, since 2.9.8+ otherwise truncates the id to 12 characters and strips the `sha256:` prefix, and broaden the prune regex to accept Docker's `Deleted Volumes:`/`Deleted Networks:` header form alongside the old `Deleted: <name>` lines. Verified end-to-end against real wslc 2.9.4 and 2.9.9 binaries. Fixes #602 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2d8021a7-70c7-4846-ba6e-b692dafd4eda
Brandon Waterloo [MSFT] (bwateratmsft)
requested a review
from a team
as a code owner
September 2, 2026 14:26
Copilot started reviewing on behalf of
Brandon Waterloo [MSFT] (bwateratmsft)
September 2, 2026 14:26
View session
These canaries exist precisely to fail when wslc gains a capability the client works around, so removing them because wslc 2.9.8+ added `--filter` defeats their purpose. Restore them unchanged; the failure is the signal working as intended. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2d8021a7-70c7-4846-ba6e-b692dafd4eda
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The new WslcListNetworkRecord.ts schema uses z.extend(...), which is likely not a valid Zod API and would break compilation.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR updates the vscode-container-client WSLC runtime adapter to tolerate WSLC 2.9.8+ changes to --format json output (Docker-shaped records and newline-delimited JSON), while remaining compatible with older WSLC releases by accepting both generations of list record shapes via Zod unions.
Changes:
- Extend WSLC list parsing to accept both legacy and Docker-shaped outputs for images and networks (including NDJSON output).
- Add
--no-trunctowslc imagesto prevent truncated image IDs in newer WSLC versions. - Broaden WSLC prune parsing to accept both legacy
Deleted: <name>lines and Docker-styleDeleted <Resource>:header output; add regression tests for both.
File summaries
| File | Description |
|---|---|
| packages/vscode-container-client/src/test/clients/WslcClient/WslcClient.test.ts | Adds regression coverage for NDJSON output and Docker-shaped records for images/networks/volumes, and new prune output formats. |
| packages/vscode-container-client/src/test/clients/WslcClient/WslcCanary.test.ts | Removes --filter canaries and replaces with a note explaining back-compat constraints. |
| packages/vscode-container-client/src/clients/WslcClient/WslcListNetworkRecord.ts | Introduces a union schema to parse both legacy and Docker-shaped network list records and normalize to ListNetworkItem. |
| packages/vscode-container-client/src/clients/WslcClient/WslcListImageRecord.ts | Updates image list schema to accept both WSLC generations, normalize to the shared shape, and treat <none> sentinels as missing data. |
| packages/vscode-container-client/src/clients/WslcClient/WslcClient.ts | Adds --no-trunc for image listing, updates list parsing comments, switches networks to the new list-record schema, and expands prune regex handling. |
| packages/vscode-container-client/src/clients/DockerClientBase/SharedListImageRecord.ts | Updates docs to reflect that WSLC now has two generations mapped onto the shared image list schema. |
| packages/vscode-container-client/src/clients/DockerClientBase/SharedInspectNetworkRecord.ts | Updates docs to reflect WSLC’s version-dependent network list output shape and the new fallback path. |
Review details
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Diffing 2.9.4 against 2.9.8 hid two intermediate releases' worth of detail. Checking every 2.9.x tag shows the framing and the record shapes changed at different times: - 2.9.5 switched all list verbs from a pretty-printed JSON array to newline-delimited objects, leaving the records untouched. - 2.9.8 replaced the `images` and `network list` records, moved volume/network prune to the header form, and added volume inspect `Scope`. - 2.9.9 replaced the `volume list` record. So the legacy record band is 2.9.7 and earlier, not 2.9.4, and 2.9.5 through 2.9.7 pair the new framing with the old records. Behavior is unaffected -- the unions and `parseInspectJson` already accepted every combination -- but the comments claimed otherwise. Adds a version table to the client doc and a test for the previously uncovered middle band. Also verified `images --no-trunc` has existed since 2.9.0, so passing it unconditionally is safe on every release. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2d8021a7-70c7-4846-ba6e-b692dafd4eda
Brandon Waterloo [MSFT] (bwateratmsft)
enabled auto-merge (squash)
September 2, 2026 15:19
Patrick Verbrugge (patverb)
approved these changes
Sep 2, 2026
Brandon Waterloo [MSFT] (bwateratmsft)
deleted the
agents/fix-bug-602-wslc-versions
branch
September 2, 2026 18:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖
Summary
Fixes #602. When wslc is the configured runtime, the Images view failed with a Zod validation error (
Idexpected,Createdexpected) and reported "failed to connect".wslc changed its
--format jsonoutput twice. I checked every 2.9.x tag rather than just the endpoints, because the framing and the record shapes changed at different times:imagesandnetwork listrecords: native → Docker's all-string shape.volume/network prune:Deleted: <name>→ header + bare names. VolumeinspectgainsScope.network list/volume listgain--filter.volume listrecord: native → Docker's all-string shape.Two consequences worth noting: the legacy record band is 2.9.7 and earlier (not 2.9.4), and 2.9.5–2.9.7 pair the new framing with the old records — so neither framing nor record shape alone identifies a generation.
list(containers) has kept its native record throughout, including in 2.9.9.The schemas only knew the oldest shapes, so every record failed validation on 2.9.8+.
What changed
Rather than switching formats outright — which would break users on 2.9.3–2.9.7 — the schemas now accept both record generations via Zod unions, so a single build works against any release from 2.9.0 to 2.9.9.
WslcListImageRecord.ts— union of the 2.9.8+ Docker shape and the legacy shape, both normalized ontoSharedListImageRecord. Added a<none>sentinel filter so untagged images stay unnamed rather than becoming<none>:<none>.WslcListNetworkRecord.ts(new) — same treatment fornetwork list.WslcClient.ts— added--no-trunctoimages, and broadenedWslcPruneDeletedRegexto accept Docker'sDeleted Volumes:/Deleted Networks:header form alongside the oldDeleted: <name>lines. The class doc now carries the version table above.The two image shapes are disjoint (
ID/CreatedAtvsId/Created), so a record belonging to neither generation is still rejected rather than silently parsing as an empty image — this keeps the existing "skips a malformed record in non-strict mode" behavior intact.list(containers) andvolume listneeded no code change: the former is unchanged, and the latter already parsed through the existing tolerant shared schema. Regression tests lock both in, along with the 2.9.5–2.9.7 middle band.Why
--no-truncWithout it, 2.9.9 returns a 12-character id with the
sha256:prefix stripped:That would have silently corrupted image identity even after the schema fix.
imageshas accepted--no-truncsince 2.9.0, so passing it unconditionally is safe on every release. Notenetwork listhas no--no-truncbefore 2.9.8, so network ids remain truncated to 12 chars.Verification
Verified end-to-end against both real binaries — 2.9.4 locally, then updated to the 2.9.9 pre-release (the version from the bug report) and re-verified. All list, inspect, and prune paths parse correctly on both: images, containers, networks, volumes, all four
inspecttypes, client-side label filtering, and both prune verbs. Intermediate versions were verified from the wslc sources at each tag.Testing against the real 2.9.9 binary corrected two details my initial fixtures had wrong, and the verbatim strings are now in the tests:
2026-09-01 17:44:01.0498728 +0000 UTC).Total reclaimed space: 0Bhas no space before the unit (2.9.8 switchedFormatBytes→FormatHumanReadableSize). This matters because the prune regex must not mistake that line for a deleted resource — there's now a "nothing deleted" case using the real no-op output.Full workspace build, lint (
--max-warnings 0), and 571 unit tests pass.--filtercanaries now fail on wslc 2.9.8+ — by designWslcCanary.test.tsis unchanged by this PR, and running it against 2.9.9 produces two intentional failures:This is the canary doing its job: wslc 2.9.8 added
--filtertonetwork list/volume list, and the canary is telling us the client-sidematchesLabelFiltersworkaround is now removable.This PR deliberately does not act on that signal, because adopting
--filterwould break wslc 2.9.3–2.9.7, which reject unknown arguments outright. Doing it properly needs runtime version detection that the client doesn't have today — a larger change than this bug fix should carry. Flagging it for a follow-up decision on whether to add version detection or simply drop support for pre-2.9.8 wslc.The other six canaries still pass, confirming
events,info,container restart,--expose,--add-host, and--platformremain absent even in 2.9.9.Also noted for future work: 2.9.9 added
--mountand--iptorun. The existing--volumeworkaround was left alone as out of scope here.Per repo policy,
CHANGELOG.mdandNOTICE.htmlwere left untouched.