Repository navigation
cardkit-net: serialize frames through explicit polymorphic serializers - #22
Merged
Merged
Conversation
Fixes a wasm-only runtime crash that 500's web e2e caught and no JVM test can: with sealed hierarchies the reified encodeToString<ClientMessage>(...) lookup found the generated serializer on every target, but now that the bases are plain interfaces the JVM resolves one reflectively while Kotlin/Wasm cannot, and throws "explicitly declared serializer should be used for interfaces" on the client's first outbound frame. ClientMessageSerializer/ServerMessageSerializer are now the API, used by both the client and the server transport. No reified-interface call sites remain in either module, which is what stops this recurring. The goldens are unchanged and still pass. That is the lesson worth keeping: open polymorphism is byte-identical on the wire but not lookup-identical across targets. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019EH6XkA2oEhv4YnMXt8hbJ Signed-off-by: rotund_tapir <rotund_tapir@protonmail.com>
rotundtapir
commented
Jul 29, 2026
rotundtapir
left a comment
Owner
Author
There was a problem hiding this comment.
Reviewed: precisely the fix from the 500#36 diagnosis — ClientMessageSerializer/ServerMessageSerializer as published PolymorphicSerializers, frame call sites switched off the reified form, and the KDoc carries the cross-target rationale so the rule survives its discoverer. Single commit authored/pushed by rotundtapir, CI green. Merging; 500#36 re-pins and its web e2e becomes the live proof on the wasm target.
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.
Fixes a wasm-only runtime crash that 500's web e2e caught on its adoption PR (500#36) and that no JVM test can see.
With sealed hierarchies,
encodeToString<ClientMessage>(…)'s reified lookup found the generated serializer on every target. Now that the bases are plain interfaces, the JVM still resolves one reflectively at runtime — but Kotlin/Wasm has no such fallback and throwsSerializer for class 'ClientMessage' is not found … explicitly declared serializer should be used for interfaceson the client's very first outbound frame. Every JVM suite and android-e2e stayed green while the browser build died on connect.ClientMessageSerializer/ServerMessageSerializerare now the API, and the client and the server transport both use them. There are no reified-interface call sites left in either module, which is what stops this recurring.The goldens are unchanged and still pass, which is the point worth taking away: open polymorphism is byte-identical on the wire but not lookup-identical across targets. Recorded in CLAUDE.md, along with the fact that this repo has no wasm unit test (browser tests need a real Chrome), so the games' Playwright suites are the only stage that exercises the wasm client — which is why they gate merges.
Verified:
:cardkit-net:jvmTest,:cardkit-server:test,:cardkit-net:compileKotlinWasmJs. The real proof is 500#36 and euchre going green on their web e2e after re-pinning; I'm running 500's locally now.🤖 Generated with Claude Code
https://claude.ai/code/session_019EH6XkA2oEhv4YnMXt8hbJ