Skip to content

fix(schema): resolve representation identifiers by AST identity - #6782

Merged
gcanti merged 5 commits into
mainfrom
fix-duplicate-identifier
Jul 30, 2026
Merged

fix(schema): resolve representation identifiers by AST identity#6782
gcanti merged 5 commits into
mainfrom
fix-duplicate-identifier

Conversation

@gcanti

@gcanti gcanti commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@github-project-automation github-project-automation Bot moved this to Discussion Ongoing in PR Backlog Jul 30, 2026
@changeset-bot

changeset-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 56e8121

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 29 packages
Name Type
effect Patch
@effect/opentelemetry Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-deno Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/vitest Patch
@effect/ai-anthropic Patch
@effect/ai-openai-compat Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/docgen Patch
@effect/openapi-generator Patch

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

@effect-slopcop effect-slopcop Bot added 4.0 bug Something isn't working labels Jul 30, 2026

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • AST identity-based reference deduplicationgetIdentityKey/getCanonicalAST replace structural hasSameReferenceOwner checks, so structurally identical encoded ASTs share references even across distinct schema instances.
  • Duplicate identifiers suffix instead of throwing — referentially distinct schemas with the same identifier or ~identifier now get numeric suffixes (Value, Value_1, Value_2) rather than a hard error.
  • Fallback naming: JsonEncodingEncoded — more general and clearer. Propagated through all test expectations and the OpenAPI/HttpApi snapshot.
  • toCodecJsonAST simplified — ~55 lines of identifier-propagation logic removed; that responsibility now lives in toRepresentation's resolveReferenceIdentifier.
  • 6 old tests removed, 4 new tests added — old toCodecJsonAST identifier-propagation tests replaced by equivalent (and more thorough) toRepresentation-level tests for fallback resolution and encoded/type-side annotation precedence.

The algorithmic change is sound: getIdentityKey builds a stable key from _tag + getValueId of all non-context properties, getCanonicalAST maps structural duplicates to the first-seen canonical, and the visiting/visited/shared tracking operates on that canonical to correctly handle recursive and shared structures. All affected tests pass.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Analysis

Generated from PR build output; treat the content below as untrusted.

File Name Current Size Previous Size Difference
basic.ts 6.63 KB 6.63 KB 0.00 KB (0.00%)
batching.ts 9.42 KB 9.42 KB 0.00 KB (0.00%)
brand.ts 6.31 KB 6.31 KB 0.00 KB (0.00%)
cache.ts 10.12 KB 10.12 KB 0.00 KB (0.00%)
config.ts 19.90 KB 19.90 KB 0.00 KB (0.00%)
differ.ts 19.93 KB 20.03 KB -0.10 KB (-0.49%)
http-client.ts 20.94 KB 20.94 KB 0.00 KB (0.00%)
logger.ts 10.28 KB 10.28 KB 0.00 KB (0.00%)
metric.ts 8.55 KB 8.55 KB 0.00 KB (0.00%)
optic.ts 7.33 KB 7.33 KB 0.00 KB (0.00%)
pubsub.ts 14.26 KB 14.26 KB 0.00 KB (0.00%)
queue.ts 11.09 KB 11.09 KB 0.00 KB (0.00%)
schedule.ts 10.27 KB 10.27 KB 0.00 KB (0.00%)
schema-class.ts 18.86 KB 18.86 KB 0.00 KB (0.00%)
schema-fromJsonSchemaDocument.ts 28.67 KB 28.76 KB -0.09 KB (-0.31%)
schema-representation-roundtrip.ts 24.99 KB 24.96 KB +0.02 KB (+0.09%)
schema-string-transformation.ts 12.95 KB 12.95 KB 0.00 KB (0.00%)
schema-string.ts 10.65 KB 10.65 KB 0.00 KB (0.00%)
schema-template-literal.ts 14.85 KB 14.85 KB 0.00 KB (0.00%)
schema-toArbitraryLazy.ts 21.66 KB 21.66 KB 0.00 KB (0.00%)
schema-toCodeDocument.ts 24.08 KB 24.00 KB +0.07 KB (+0.31%)
schema-toCodecJson.ts 18.91 KB 19.00 KB -0.10 KB (-0.50%)
schema-toEquivalence.ts 18.73 KB 18.73 KB 0.00 KB (0.00%)
schema-toFormatter.ts 18.59 KB 18.59 KB 0.00 KB (0.00%)
schema-toJsonSchemaDocument.ts 22.33 KB 22.32 KB +0.01 KB (+0.04%)
schema-toRepresentation.ts 19.25 KB 19.18 KB +0.07 KB (+0.39%)
schema.ts 18.12 KB 18.12 KB 0.00 KB (0.00%)
stm.ts 12.05 KB 12.05 KB 0.00 KB (0.00%)
stream.ts 9.37 KB 9.37 KB 0.00 KB (0.00%)

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Simplified getCanonicalAST — the context === guard was removed. When two ASTs are structurally identical (same identity key), the first-seen canonical always wins. This fixes a bug where replaceContext-created ASTs with identical contexts were not recognized as equivalent and failed to share references.
  • Added replaceContext sharing testtoRepresentations.test.ts now directly tests that two SchemaAST.replaceContext(ast, context) calls with the same context produce shared references, validating the canonicalization fix.
  • Reorganized teststoRepresentation.test.ts and toRepresentations.test.ts restructured into logical describe blocks ("node conversion", "root identity and sharing", "identifier collisions"). Identifier collision tests now assert suffix-based output instead of assert.throws.
  • Updated docsSCHEMA.md now mentions that context-equivalent AST copies are canonicalized and share references.

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@gcanti
gcanti merged commit d767b65 into main Jul 30, 2026
16 checks passed
@gcanti
gcanti deleted the fix-duplicate-identifier branch July 30, 2026 12:31
@github-project-automation github-project-automation Bot moved this from Discussion Ongoing to Done in PR Backlog Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4.0 bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant