Separate the default variant cache key from named variants - #6973
Conversation
🦋 Changeset detectedLatest commit: 62087e7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 30 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Important
The regression test correctly reproduces the cache collision, but this PR only adds the test. The VariantSchema.ts implementation fix required by the PR title is not present, so CI will remain failing.
Reviewed changes
- Added one regression test in
packages/effect/test/unstable/schema/VariantSchema.test.tsthat verifies a variant literally named__defaultextracts its own schema even after the default variant has been extracted.
⚠️ Implementation fix is missing
The test fails as expected against main because extract still uses a single cache key "__default" for both the default-variant extraction and the literal __default variant:
packages/effect/src/unstable/schema/VariantSchema.ts:218—const cacheKey = options?.isDefault === true ? "__default" : variantpackages/effect/src/unstable/schema/VariantSchema.ts:28—cacheSymboldeclares a single cache.
To satisfy the expected behavior stated in the PR description, the named-variant cache and the default-variant cache need to be separated (e.g., a second defaultCacheSymbol/cache object, or an equivalent namespacing scheme). Remember to also update the [cacheSymbol]?: Record<string, Schema.Top> type in Struct's interface if the cache structure changes.
Technical details
# Separate default-variant cache from named-variant cache
## Affected sites
- `packages/effect/src/unstable/schema/VariantSchema.ts:28-40` — type of `Struct` cache may need adjustment
- `packages/effect/src/unstable/schema/VariantSchema.ts:216-241` — cache-key logic collides
## Required outcome
- Extracting the configured default variant must not pollute the cache entry used by a literal variant named `__default`.
- Extracting a literal `"__default"` variant must not pollute the default-variant cache entry.
- Existing tests and the new regression test pass.
## Suggested approach
Introduce a separate cache for default-variant extractions (e.g., `defaultCacheSymbol`). Use `variant` as the key within each cache. The `isDefault` check should route to the appropriate cache bucket.ℹ️ Nitpicks
- Consider adding a second assertion or parameterizing the test so it also covers the reverse order: extract
__defaultfirst, then extract the default variant. That proves the collision is avoided regardless of which entry populates the cache first.
@v0 or keep the SHA fresh with Dependabot | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Added a second
defaultCacheSymbol-backed cache inpackages/effect/src/unstable/schema/VariantSchema.tsand routed default-variant extractions through it, removing the"__default"sentinel collision with a literal__defaultvariant. - Updated the
Structinterface to declare both[cacheSymbol]and[defaultCacheSymbol]optional caches. - Expanded the regression test in
packages/effect/test/unstable/schema/VariantSchema.test.tsto cover both extraction orders: default variant first, then literal__default; and literal__defaultfirst, then default variant. - Added a patch changeset in
.changeset/fix-variant-schema-default-cache.mddescribing the cache separation.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
1fde2db to
538e97e
Compare
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Re-reviewed the branch after the force-push/amend that replaced the previously approved commits. The cache-separation fix remains equivalent to the previously approved version:
- Added
defaultCacheSymboland routedisDefault: trueextractions to the separate default-variant cache inpackages/effect/src/unstable/schema/VariantSchema.ts. - Updated the
Structinterface to declare both optional caches. - Expanded the regression test in
packages/effect/test/unstable/schema/VariantSchema.test.tsto cover both cache-population orders. - Added the patch changeset in
.changeset/fix-variant-schema-default-cache.md.
Validation run: pnpm --filter effect test --run test/unstable/schema/VariantSchema.test.ts, pnpm lint-fix, and pnpm check all pass.
ℹ️ PR description is now stale
The PR body still describes the implementation fix as pending and says CI is expected to fail. The fix is present on the branch, so that section is now misleading.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏
Bundle Size AnalysisGenerated from PR build output; treat the content below as untrusted.
|
538e97e to
62087e7
Compare
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Re-reviewed after the force-push to 62087e7a. The new commits contain the same cache-separation fix as the previously approved version:
- Added
defaultCacheSymbolinpackages/effect/src/unstable/schema/VariantSchema.tsand routedisDefault: trueextractions to the separate default-variant cache. - Updated the
Structinterface to declare both[cacheSymbol]and[defaultCacheSymbol]optional caches. - Expanded the regression test in
packages/effect/test/unstable/schema/VariantSchema.test.tsto cover both cache-population orders. - Added the patch changeset in
.changeset/fix-variant-schema-default-cache.md.
Validation run: pnpm --filter effect test --run test/unstable/schema/VariantSchema.test.ts, pnpm check, and pnpm lint-fix all pass.
@v0 or keep the SHA fresh with Dependabot | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Summary
A configured variant literally named __default can return the selected default variant's schema instead of its own.
Important
This PR starts with focused failing reproduction tests. Add the implementation fix to this same branch; CI is expected to fail until that fix is included.
Variant __default collides with the default cache key
Module:
schema/VariantSchemaAudit ID:
unstable-ai-cli-variant-schema-default-cache-collisionSeverity / confidence: medium / high
What happens
A configured variant literally named __default can return the selected default variant's schema instead of its own.
Why it happens
Default extraction and the ordinary __default variant share the same string cache key, so whichever is extracted first populates the other's entry.
Expected behavior
Every accepted string in options.variants extracts its configured schema independently of the selected default variant.
Relevant implementation
These links and excerpts are pinned to audit base
c9b56ab507f224426ee8388dc450da447ec4715f.packages/effect/src/unstable/schema/VariantSchema.ts:28packages/effect/src/unstable/schema/VariantSchema.ts:198-220packages/effect/src/unstable/schema/VariantSchema.ts:486-491View problematic code at
packages/effect/src/unstable/schema/VariantSchema.ts:28View exact lines on GitHub
View problematic code at
packages/effect/src/unstable/schema/VariantSchema.ts:198-220View exact lines on GitHub
View problematic code at
packages/effect/src/unstable/schema/VariantSchema.ts:486-491View exact lines on GitHub
Reproduction
pnpm test --run packages/effect/test/unstable/schema/VariantSchema.test.tsObserved failure: FAIL: the named variant was replaced by the cached default schema.
Implementation handoff
The initial reproduction tests on this branch are the regression specification for the implementation fix that should follow in this PR.
pnpm test --run packages/effect/test/unstable/schema/VariantSchema.test.tsAudit provenance
c9b56ab507f224426ee8388dc450da447ec4715fc9b56ab507f224426ee8388dc450da447ec4715funstable-ai-cli-variant-schema-default-cache-collisionCloses EFF-414