Schema encoding can return an internal symbol across module copies

Chiusa
#10,381 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Una pull request collegata è già stata integrata.

  • #10382 di @schickling-assistant — integrata

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
25/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Ferma
Stack tecnologico
typescript

Direzione di ricerca

Start with packages/effect/test/schema/HMR.test.ts and reproduce the two failing cases using separate imports after vi.resetModules(). Then read internal/schema/parser.ts and trace how missing, missingExit, and sameExit are compared by the parser and its consumers. Done means the regression tests return the original empty string and false across module copies; an open linked pull request is already addressing the issue.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Schema encoding can return an internal symbol across module copies

Reproduction

Reproduced on main at c0981a29044194e7e1ad35cb7aad02c5849d5aab. Two independently loaded Effect module graphs in the same realm can disagree about parser sentinels:

import { expect, it, vi } from "vitest"

it.each(["", false])("encodes %j across module copies", async (input) => {
  const A = await import("effect/Schema")
  vi.resetModules()
  const B = await import("effect/Schema")
  const schema = typeof input === "string" ? A.String : A.Boolean
  expect(B.encodeSync(schema)(input)).toBe(input)
})

Expected: "" and false, respectively. Actual: Symbol() in both cases. The equivalent regression added to packages/effect/test/schema/HMR.test.ts fails twice before the fix (the five existing tests pass).

This surfaced in LiveStore DevTools, where the application creates schemas and a separately bundled DevTools copy of Effect encodes them.

Root cause

internal/schema/parser.ts allocates module-local missing, missingExit, and sameExit. AST parser methods retain their creating module's sentinels, while SchemaParser and the interpreter/codegen consumers compare against their own sentinels by identity. An unrecognized foreign sameExit is treated as an ordinary success containing a foreign missing symbol, which escapes as the encoded value.

Sharing only missing is insufficient: sameExit is also identity-sensitive and means “return the original input,” not “return missing.” A namespaced same-realm global registry can share the exit objects as well as the missing symbol. This addresses copies implementing the shared protocol; it does not retrofit an already loaded unpatched copy or transfer identities across realms.

Related precedent: #1561 (CJS–ESM hazard).

Posted on behalf of @schickling
field value
agent_identity agent/livestore/owner
session 01a1f40c
agent_persona generalist
agent_supervisor unavailable
agent_tool OMP
agent_tool_version 18.12.5
agent_runtime OMP 18.12.5
agent_model anthropic/claude-opus-5-5
worktree unknown
Lingua principale
TypeScript
Stelle
16.7k
Fork
808
Merge medio
11h 40m
PR unite (30g)
827

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Effect-TS/effect

Tutte le issue di Effect-TS/effect

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.