Note: This is an AI-assisted investigation summary and has not been manually confirmed yet. I plan to verify the findings myself and, if they hold up, submit a PR with the fix.
I did some investigation on release/6.3 in a clean Ubuntu aarch64 environment.
I created a small DemoKit set of packages covering:
- a plain SwiftPM library package
- a build-tool-plugin package
- a macro package
The plain package and build-tool-plugin package did not reproduce the issue in my loops. The macro package did reproduce it with the system Swift 6.2.4 toolchain, especially when building with --disable-experimental-prebuilts:
Internal Error: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "Corrupted JSON", underlyingError: Optional(unexpected end of file)))
The failure appears to come from the macro / in-process plugin path, not the SwiftPM PackagePlugin IPC path.
The key finding is that release/6.3 has a teardown path that sends an empty plugin message. That is fine as a stream-level termination signal for a pipe-backed executable plugin, but the in-process plugin server handles each sendMessage call as one complete JSON request and decodes it directly. When it receives the empty message, it tries to decode "" as JSON, which produces the observed EOF / corrupted JSON diagnostic.
The relevant area is:
swift/lib/AST/PluginRegistry.cpp
swift/include/swift/AST/PluginRegistry.h
swift/tools/swift-plugin-server/Sources/SwiftInProcPluginServer/InProcPluginServer.swift
A local fix that worked for me was:
- Make the in-process plugin
sendMessage path treat an empty message as a no-op, since there is no stream to tear down there.
- Remove the teardown-time empty message expectation from the affected macro tests.
After applying that, I built a release/6.3 Linux toolchain and reran the repro matrix:
3 packages x 3 build command variants x 50 iterations = 450 builds
I scanned all logs for:
Internal Error:
Corrupted JSON
unexpected end of file
and the issue did not reproduce anymore.
I also ran the targeted macro lit tests I touched; the relevant tests passed, with one unsupported on this Linux configuration.
So my current hypothesis is that this specific “Corrupted JSON / unexpected end of file” diagnostic is caused by an empty teardown message being routed through the in-process macro plugin JSON decoder. I will follow up after manually confirming the repro and the fix.