Schema: idiomatic way to encode against a type-erased `Schema.Top` (codec services show as `unknown` in the requirements channel)?
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Tranquilo
- Stack tecnológico
- typescript
- Área
- api
Línea de trabajo
Start with the Schema.Top, Schema.toCodecJson, Schema.encodeUnknownEffect, encodeUnknownExit, and encodeUnknownResult APIs, then run the linked reproduction with bun install and bun run repro. Compare the reported R=unknown and R=never assertions and runtime check; done would require an agreed idiomatic way to encode or decode service-free type-erased schemas without an unsafe cast.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
This is a usage/idiom question about encoding against type-erased schemas.
When you only have a type-erased Schema.Top — e.g. from RPC dynamic dispatch, heterogeneous registries, or plugin systems where the concrete schema type is lost — encoding a value against it as JSON surfaces unknown in the requirements (R) channel:
declare const erased: Schema.Top
const eff = Schema.encodeUnknownEffect(Schema.toCodecJson(erased))(value)
// eff: Effect<Json, SchemaError, unknown> // <- unknown in R
Schema.Top types DecodingServices/EncodingServices as unknown, and toCodecJson + encodeUnknownEffect forward them into R. @effect/language-service flags it as anyUnknownInErrorContext (TS377030, "unknown in the requirements channel"). But such schemas are plain data — they need no codec services (the repro verifies this at runtime).
The only clean fix we found is an unsafe cast asserting the (true) never service channels:
Schema.toCodecJson(erased as Schema.Codec<unknown, unknown, never, never>)
// -> Effect<Json, SchemaError, never>
We confirmed encodeUnknownExit / encodeUnknownResult (which return Exit/Result with no R channel) don't avoid the cast — their ConstraintEncoder<unknown> bound requires EncodingServices extends never, which Schema.Top doesn't satisfy.
Question: is casting the service channels the idiomatic way to encode/decode against a Schema.Top known to need no services, or is there a cleaner, more Effect-native API for this (a service-erasing combinator, an encode variant that ignores services, a better way to type-erase RPC schemas, etc.)?
Reproduction
https://github.com/schickling-repros/2026-07-effect-erased-schema-services
bun install
bun run repro # tsc type-assertions (R=unknown vs R=never) + a runtime check
Versions
- effect:
4.0.0-beta.98 @effect/language-service:anyUnknownInErrorContext(TS377030)
Context: this arises encoding RPC exit/payload schemas after dynamic dispatch erases them to Schema.Top — a follow-on to #6064 (which exposed successSchema but not the service-typing question).
Posted on behalf of @schickling
| field | value |
|---|---|
agent_name |
🌲 cl1-pine |
agent_session_id |
b9f1f4a5-dd10-40f6-b25c-945e71e2007a |
agent_tool |
Claude Code |
agent_tool_version |
2.1.206 |
agent_runtime |
Claude Code 2.1.206 |
agent_model |
claude-opus-4-8 |
runtime_profile |
/nix/store/1n76sy6i9y3ki3k4w04jksqvygw67sj0-coding-agent-runtime-profile/share/coding-agents/profile.json |
skills_manifest |
/nix/store/jn6r0r7r59x3a525jch4pwzwykszqp60-agent-skills-corpus/share/agent-skills/manifest.json |
worktree |
livestore/schickling/2026-07-17-refactor |
machine |
dev3 |
tooling_profile |
dotfiles@4eac376 |
- Lenguaje dominante
- TypeScript
- Estrellas
- 16.7k
- Forks
- 808
- Merge medio
- 10 h 33 min
- PR fusionados (30 d)
- 830
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de Effect-TS/effect
-
RpcTest.makeClient: accept disableFatalDefectsPosiblemente ocupada @effect-bot la tomó hace 1 día. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Effect-TS/effect#9893 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
`HttpApiSchema.Upgrade`: allow a regular success for servers that don't upgradePosiblemente ocupada @effect-bot la tomó hoy. Abiertodocker-made-me-do-it enhancement
Effect-TS/effect#9912 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
docker-made-me-do-it enhancement
Dificultad 5/5 Más de una semana Aptitud para principiantes 20/100
Los mantenedores suelen responder en 1 día
-
`HttpApiSchema`: stream bodies in a custom framingPosiblemente ocupada @effect-bot la tomó hoy. Abiertodocker-made-me-do-it enhancement
Effect-TS/effect#9910 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
`HttpApiSchema` streams: declare every media type a stream can be sent asPosiblemente ocupada @effect-bot la tomó hoy. Abiertodocker-made-me-do-it enhancement
Effect-TS/effect#9909 · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de Effect-TS/effect
Issues similares
-
type: bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 79/100
Los mantenedores suelen responder en 1 día
-
0️⃣ phase/new
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 70/100
microsoft/playwright#43640 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100