fix(core): decode plugin tool input with the schema's own instance - #43460
Open
argszero wants to merge 1 commit into
Open
fix(core): decode plugin tool input with the schema's own instance#43460argszero wants to merge 1 commit into
argszero wants to merge 1 commit into
Conversation
Contributor
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
argszero
force-pushed
the
fix-plugin-schema-drift
branch
4 times, most recently
from
August 19, 2026 23:26
9bffaa7 to
7a43be7
Compare
argszero
force-pushed
the
fix-plugin-schema-drift
branch
from
August 20, 2026 01:30
7a43be7 to
98f534d
Compare
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.
Issue for this PR
Closes #43322
Type of change
What does this PR do?
When a config plugin bundles a different
effectversion than the server, every tool input decode failed withInvalid tool input: Expected object— input-independent, for every tool, until the plugin'seffectwas manually realigned. Root cause: the plugin's schema still passes the hostSchema.isSchemacheck (the~effect/Schema/SchemaTypeId string is stable across versions), sodecodeInputran the host'sSchema.decodeUnknownEffecton the foreign AST, which the host decoder cannot interpret.This PR makes
decodeInputinpackages/core/src/tool/runtime.tsfall back to the schema's own constructor (schema.makeEffect), which validates with the schema's own instance and is therefore version-agnostic:Tool.Error.hasTransformationshelper that walks the schema AST forencodingnodes (struct fields, arrays, unions, tuples, records). Schemas with transformations or decoding defaults keep the plain host decode, because theirmakeview (type side) differs from their decoded view — a naive fallback there could silently accept input the decoder would reject. Inspection failures (e.g. decoding-default schemas whose AST accessor throws) also keep the plain path.Reproduced and verified end-to-end against a real foreign schema built with
effect@4.0.0-beta.101loaded into thebeta.107server: valid input now decodes successfully (previouslyExpected object), and invalid input is rejected withInvalid tool input: Expected number, got "no" at ["bar"].The
encodeOutputpath has the same theoretical drift exposure for plugin tools that declare output schemas, but effect schemas expose no version-agnostic encode primitive on the instance, so that is left as a follow-up.How did you verify your code works?
bun test ./test/tool-schema.test.tsfrompackages/core: 10 passed, including a new regression test that simulates a drifted schema (mutated AST the host decoder rejects while the schema's own constructor still validates) and asserts valid input decodes, invalid input is rejected, and same-host schemas behave unchanged.session-runner-tool-registry.test.ts) passes unchanged — it guards the no-fallback-for-transforms gate.bun testfrompackages/core: 1891 passed, 16 skipped, 0 failed.bun typecheckfrompackages/coreand repo-widebun typecheck(33 tasks): passed.Screenshots / recordings
N/A (not a UI change)
Checklist