Patch Changes
-
#9990
56bbd6fThanks @effect-bot! - AddRational, an exact fraction type alongsideBigDecimal, withSchema.RationalandSchema.RationalFromString.import { BigDecimal, Rational } from "effect" const third = Rational.makeUnsafe(1n, 3n) Rational.equals(Rational.multiply(third, Rational.fromBigInt(3n)), Rational.fromBigInt(1n)) // true Rational.toBigDecimal(third, { scale: 3 }) // BigDecimal 0.333
-
#9842
7150ea1Thanks @tim-smart! - Add experimental AG-UI protocol support toeffect/aithrough the newAgUiSchema,AgUi, andAgUiServermodules, and akeepAliveoption toHttpApiSchema.StreamSse. -
#10377
da85361Thanks @effect-bot! - AddCommandSpec, a lossless projection of aneffect/clicommand path for documentation tooling, plusFlag.annotate/Argument.annotate/Param.annotatefor attaching custom metadata to parameters.import { Config, Context, Option } from "effect" import { Command, CommandSpec, Flag } from "effect/cli" const EnvVar = Context.Service<never, string>("app/EnvVar") const push = Command.make("push", { dbUrl: Flag.String("db-url").pipe( Flag.withFallbackConfig(Config.String("DB_URL")), Flag.annotate(EnvVar, "DB_URL") ) }) const cli = Command.make("app").pipe(Command.withSubcommands([push])) const spec = Option.getOrThrow(CommandSpec.resolve(cli, ["app", "push"])) for (const flag of spec.flags) { // flag.scope, flag.required, flag.fallbacks, Context.getOption(flag.annotations, EnvVar), ... }
-
#10417
95b01bbThanks @effect-bot! - Fix Bash and Zsh CLI completions for subcommand names containing:, such astest:unit. -
#10375
b09e7a8Thanks @effect-bot! - Fix CLI completion descriptors marking variadic arguments without a positive minimum as required. -
#10428
91386c0Thanks @devangpratap! - Shell completions keep suggesting repeatable flags, such asFlag.atLeastandFlag.KeyValuePair, after their first use. -
#10376
a2b1be0Thanks @effect-bot! - AllowCommand.validateto fail with your own errors, whichCommand.runreports like handler failures instead of showing help.Command.withHandlernow keeps the command's existing error type, so errors from earlier validations are not lost. When it replaces a handler, the old handler's errors also stay in the type. Code that annotates such a command with a narrower error type must widen the annotation, or pass the final handler toCommand.makeinstead. -
#7322
1a2c5a6Thanks @tim-smart! - Add experimental Cloudflare Cluster support with durable entities, workflows, queues, singletons, and optional Alchemy deployment, plus Effect hooks for keep-alive, durable clocks, and dead-letter detection. -
#10311
2a9d989Thanks @effect-bot! - FixClusterWorkflowEngineturning transient storage failures while starting a child workflow into a parent workflow defect; they are now retried. -
#10356
66cbccaThanks @Marve10s! - Fix transient storage read errors permanently failingClusterWorkflowEngineworkflows that await aDurableDeferred. -
#10267
da52437Thanks @effect-bot! - AddMessageRetention.maketo delete a persisted entity's old completed requests, and fix@effect/sql-mysql2not starting a transaction for aSET TRANSACTIONBeginTransaction.- Custom
MessageStorageimplementations must adddeleteProcessed. - SQL message storage on MySQL needs MySQL 8.0.1+ or MariaDB 10.6+, and
binlog_formatROWorMIXED.
- Custom
-
#10294
7e8f3fbThanks @effect-bot! - FixHttpMiddleware.corscalling theallowedOriginspredicate withundefinedfor requests without anOriginheader. -
#10456
1de4308Thanks @Marve10s! - FixCsv.decodeandCsv.decodeStringdropping records completed before aCsvErrorin the same input chunk. -
#10439
cb36ec7Thanks @jayhemnani9910! - Preserve the supplied time zone identifier inDateTimenamed zones, including aliases such asEurope/KyivorEtc/UTC, instead of the identifier Intl resolves them to (Europe/Kiev,UTC). -
#10506
693259dThanks @effect-bot! - FixHttpServerRequest.streamfailing on requests with no body; return an empty stream instead. -
#10448
0daaa95Thanks @effect-bot! - Speed upBase64.decode,Base64UrlandHexby using the nativeUint8ArrayBase64 and hex methods when the runtime provides them.Base64Url.encodeis also faster on runtimes without them. -
#10350
f548e59Thanks @asssslay! - Keep a leading U+FEFF when decoding strings withBase64,Base64Url,Hex, and theirSchema.StringFrom*codecs, includingHttpApiSecurity.basicusernames. -
#10413
005d096Thanks @effect-bot! - FixEqual.equalsandHash.hashtreating otherwise identicalErrorvalues as different on Bun when they were constructed at different source locations. -
#10472
188c2b0Thanks @effect-bot! - FixWorkflow.intoResultrunning workflow finalizers before handler cleanup completes when interrupted immediately after startup. -
#10450
258fb50Thanks @Marve10s! - FixHeaders.fromInputdropping earlier values for repeated header names in iterable input. -
#10006
e799258Thanks @tim-smart! - RedactHttpClientErrorrequest URLs with theUrlParams.CurrentRedactedNamesof the fiber that executed the request and of the fiber that created the error, as well as those of the fiber that renders it. -
#10496
b110d56Thanks @darjss! - Add amessagetoHttpClientErrorSchemataken from its original reason, soRpcClientErrorHTTP failures no longer read as a bareHttpError:. -
#10363
111615aThanks @effect-bot! -HttpClient.withScopenow owns every request sent while the scoped client executes, instead of tracking the request value. -
#10366
4ed0faeThanks @effect-bot! - Close a request scope transferred to a streamed body only after both the request and the body have finished, so middleware and tracing complete before request finalizers run. -
#10332
21671d5Thanks @matheuspuel! - Decode tool call parameters with their JSON codec, so aSchema.Dateparameter accepts an ISO string from MCP clients and language models.Toolkit.WithHandler.handletakesSchema.Jsonparams. Direct callers pass the JSON encoding, withnullinstead ofundefinedfor optional parameters.- With
disableToolCallResolution: true, tool callparamshold the JSON encoding and are typedSchema.Json. Provider-executed tools keep the provider's payload. - Provider-defined tools keep their provider-defined type through
setSuccess,setFailure,setParameters,setNeedsApproval,addDependency,annotateandannotateMerge, so a tool the provider runs with a dependency is not mistaken for one that needs a handler.
-
#10438
2ad19aeThanks @IfkumRfnl! - Defer formatting the source location ofAtom.withLabelandAtom.serializablelabels until it is read. -
#10455
6235a2fThanks @Marve10s! - Skip undefined handlers inMatch.tagsandMatch.discriminators, and correct exhaustiveness checks for conditional handler maps, includingMatch.literals. -
#10504
fe80e09Thanks @itisrmk! - Fix MCP2026-07-28tools/callreturning a header mismatch for tools hidden byMcpServer.visibility, which revealed that they exist. -
#10447
79af760Thanks @nmnmcc! - FixMcpServeraccepting cursors on core lists that never issue them, returningInvalidParamsinstead. -
#10509
97f8120Thanks @tim-smart! - Stop queuedMcpServerprogress notifications after their request completes, is cancelled, or disconnects, while preserving background progress notifications. -
#10398
c5383f8Thanks @fubhy! - FixMcpServer.resourceandMcpServer.registerResourceomitting the registeredmimeTypefromresources/readcontents when the handler returns a string orUint8Array. The type was only listed byresources/list, so MCP Apps hosts could not render UI resources served astext/html;profile=mcp-app. -
#10304
0d0c824Thanks @effect-bot! - TraceMcpServerrequests with spans that follow the OpenTelemetry MCP semantic conventions.Spans are now named
{method} {target}(for exampletools/call get_weather) and carrymcp.*,jsonrpc.request.idandgen_ai.*attributes instead of the genericrpc.*ones. A W3Ctraceparentinparams._metacontinues the client's trace. Tool results withisError: trueseterror.typetotool_error, and JSON-RPC errors setrpc.status_code.Toolkit.handleno longer records tool arguments on the current span by default. It recordsgen_ai.tool.nameandgen_ai.tool.call.idinstead oftoolandparameters. ProvideToolkit.RecordToolArgumentsastrueto record arguments ingen_ai.tool.call.arguments.RpcServer.makeaccepts anonRequestoption that wraps the effect running each request's middleware and handler. The callback also receives the decoded request. -
#10342
b76a52bThanks @lloydrichards! - Restrict the MCP Skills extension to protocol 2026-07-28.McpServerno longer declares or serves it on earlier revisions, andMcpClientfails withUnsupportedErrorwhenextensions: { skills: true }is paired with an earlier protocol.Clients that use Skills must select
McpProtocol.v2026_07_28. On earlier revisions, read known skill files withreadResource. -
#8506
1048919Thanks @IMax153! - Build a freshRpcServer.Protocolfor everyMcpServer.layerStdiocall. Two stdio servers merged into one layer graph previously shared a single protocol, so only the first one read itsStdio. -
#10477
def28ccThanks @effect-bot! - FixMcpServer.layerStdiohanging after stdin EOF with an open subscription while preserving accepted finite responses. -
#10434
47563e9Thanks @jpowersdev! - Reject ended transactions in MSSQLcall/withoutTransforms(), Bun SQLiteexportand libsqlreserve, and exposeSqlClient.activeTransactionConnectionfor custom drivers. -
#10426
9428e17Thanks @gcanti! - OmitcontentSchemaannotations containing references inSchemaRepresentation.fromJsonSchemaDocumentandfromJsonSchemaMultiDocumentto avoid dangling references in generated schemas. -
#10173
c45c33bThanks @ebramanti! - AddOpenRpc.fromRpcGrouptoeffect/rpc. -
#10385
077b572Thanks @effect-bot! - FixOtlpMetricsexporting metrics without a declared unit as dimensionless ("1"); they now export an empty unit.Prometheus-compatible backends no longer append
_ratioto these gauge names (for example,app_build_info_ratiobecomesapp_build_info). Update affected queries and alerts, or setattributes: { unit: "1" }on the metric to keep the previous name. -
#10440
ec4f272Thanks @okxint! -OtlpTracerandOtelTracernow leave the span status Unset instead of Ok when a span succeeds, or fails without a reportable error.OtelTracerno longer overwrites a status set directly on the span in those cases.Queries and dashboards that filter on Ok should also match Unset.
-
#10316
251e9c9Thanks @effect-bot! - Add adeduplicate: "untilExecuted"option toPersistedQueueoffer, which lets a custom id be offered again once its element completes or fails its final attempt. -
#10312
501c657Thanks @asssslay! - FixQueue.sliding(0)never waking waiting takers. Offers now hand the newest messages to waiting takers, and offers with no waiting taker are discarded instead of buffered. -
#10354
9c530cfThanks @Marve10s! - Fix zero-capacity bounded and dropping queues accepting offers without a new taker afterQueue.offerAll, which also affectedStream.buffer({ capacity: 0 }). -
#10362
781f31eThanks @tim-smart! - Encode tool results with their JSON codec, so aSchema.DateorSchema.BigIntin a tool result reaches language models, MCP clients andChat.exportJsonas JSON. Provider-executed tools keep the provider's payload.Migration
- A
Tool.dynamictool without asuccessschema must return a JSON value, even whentoModelOutputreplaces the model payload. Other values, such as aDate, now fail withToolResultEncodingError. Declare asuccessschema, for exampleSchema.Date, or return a JSON value. Declaresuccess: Schema.Voidfor a dynamic tool that returnsundefined. encodedResultof aSchema.Voidtool, includingTool.makewithout asuccessschema, is nownullinstead ofundefined.
- A
-
#10066
8cf23adThanks @jpowersdev! - FixHttpStaticServerresponding200instead of304when anIf-None-Matchentity-tag contains a comma. -
#10367
abe3084Thanks @effect-bot! - FixEffect.race,Effect.raceFirst,Effect.raceAll,Effect.raceAllFirstandEffect.timeoutOptionsometimes letting a loser finish after the race settled, which could drop its result, such as an item taken from aQueue. -
#10390
0d338bbThanks @effect-bot! - Fix fail-mode fixed-windowRateLimiterchecks admitting more thanlimitrequests perwindowand reporting a shortenedresetAfter. -
#10324
ecd5ef5Thanks @fubhy! - MeasureRcMapidle time, includingRcMap.touch, on the clock of the context the map was made in, and run idle timers in that context instead of the last borrower's. -
#10425
324e7a1Thanks @effect-bot! - Requests with the same fields and values now compare equal withEqual.equalsregardless of the order their fields were provided in. -
#10407
4e86690Thanks @effect-bot! - Speed up type-checking of flatRpcClientcalls andAtomRpcquery/mutationfor large RPC groups. Selecting an RPC by tag no longer tests every RPC in the group, which cuts instantiations about 5x and brings peak checker memory down to roughly the level of the object-shaped client.The flat client's
asQueue: trueresult now includesCause.Donein the dequeue error type, matching the object-shaped client and the runtime, which ends the queue withQueue.end.Adds the
Rpc.ByTag,RpcClient.RpcClient.Options,RpcClient.RpcClient.Result,AtomRpc.QueryandAtomRpc.Mutationutility types. -
#10418
a871b92Thanks @jpowersdev! - Allow RPC handlers to fail with their server middleware's errors without repeating them in the RPC'serrorschema.- Handlers returned by
RpcGroup.accessHandlercan now fail with those middleware errors. Handle them, or widen error types that previously allowed only the RPC's own errors.
- Handlers returned by
-
#10424
ddb8fd4Thanks @nikhilsnayak! - Fix framed HTTP RPC batches hanging when requests rejected during dispatch produce more responses thanstreamBufferSize. -
#10288
6e57c49Thanks @fubhy! - FixSchemaBinaryencoding non-number elements of a number array asNaNor0instead of failing with "Expected a number" when an earlier element needs 64-bit float encoding, such as"x"in[Math.PI, "x"]. -
#10327
7b39595Thanks @effect-bot! - Speed upSchemaBinaryencoding of largeUint8Arraypayloads without changing the wire format.Uint8Arrayvalues of 16 KiB or more are now copied when the encode call returns, after the whole batch forencodeMany, so they must not change during the call. If such a value's length changes, for example because its buffer is detached, the encode fails with aSchemaError. Frames that contain these values are returned in their own buffer instead of a view into the shared output buffer. -
#9612
422a1b3Thanks @fubhy! - Prevent built-in prototype methods from being mistaken for user-suppliedSchema.Structfield values. For example,Schema.Struct({ toString: Schema.optionalKey(Schema.String) })now accepts{}instead of failing because the inheritedtoStringfunction is not a string.Declared fields whose names are owned by
Object.prototypenow require an own property, even on inputs with custom prototypes. This lets absent optional fields stay absent and decoding defaults run; missing required fields report a missing key. Other field names retain inherited-property support. -
#10382
5a7c02fThanks @schickling-assistant! - Fix Schema encoding and decoding of schemas created by another copy ofeffect, which could return an internal symbol instead of the input or reject a missing optional key; both copies must include this fix. -
#10348
24f2274Thanks @effect-bot! - FixSchema.toIsotyping nested class fields as class instances forSchema.TaggedUnionandSchema.brandschemas. -
#10355
da0c792Thanks @effect-bot! - FixisAnyOfonSchema.TaggedUnionandSchema.toTaggedUnionunions accepting keys that are not tags of the union, so misspelled tags and widestringarrays are now type errors.- Bound generic key parameters by the union's tags, for example
<K extends Types.Tags<typeof Shape.Type>>or<K extends keyof typeof Shape.cases>, instead of<K extends string>. - For a tag list only known at runtime, use a plain boolean predicate such as
(value: Shape): boolean => names.includes(value._tag). Filtering the list down to the union's tags makesisAnyOfcompile, but its false branch then excludes every tag in the filtered type, even if the list is empty at runtime.
- Bound generic key parameters by the union's tags, for example
-
#10453
f43a02aThanks @Marve10s! - FixSchema.toEquivalenceandSchema.toFormatterto derive consistently from the decoded type side, including records with transformed keys.Schema.toFormatter'sonBeforehook now receives type-side AST nodes without encoding transformations. Update hooks that depend on encoding metadata or original AST identities to use decoded AST nodes. UseSchema.overrideToFormatterto attach formatting to a specific schema. -
#10317
c32ad61Thanks @effect-bot! - StopScopedCacheentries whose lookup registers a finalizer from retaining the first requester's span and its response until the entry is removed. -
#10451
724e62dThanks @Marve10s! - Interrupt pendingScopedCache.getandScopedCache.getOptioncalls when their lookup completes after the cache's owner scope closes. -
#10387
13c0e77Thanks @effect-bot! - Fix providing a genericSqlClientlayer removing a driver service such asPgClientfrom an effect's requirements. The program type-checked as runnable but failed at runtime withService not found.A driver client is no longer a subtype of
SqlClient.SqlClient. Code that picks between driver layers, such ascond ? PgClient.layer(...) : MysqlClient.layer(...), may need an explicitLayer.Layer<SqlClient.SqlClient, E>annotation. -
#10435
1f33b58Thanks @jpowersdev! - Allow interrupting a nestedwithTransactionwhile it waits for another nested transaction to release the savepoint. -
#10508
68e628dThanks @effect-bot! - Skip savepoint release when an ancestor transaction ends during rollback, preserving the original failure without using the released connection. -
#10433
a26ad63Thanks @jpowersdev! - Fail SQL statements and nested transactions from a fiber that outlives the transaction it was forked in, instead of running them on that transaction's connection. -
#10454
ded4ccfThanks @Marve10s! - FixSqlClient.withoutTransforms()keeping query name transforms when no result transform is configured, andStatement.makeignoring its compiler when called again with the same acquirer. -
#10475
31368abThanks @effect-bot! - Fix RPC and MCP stdio servers exiting with code 130 instead of 0 after stdin closes and pending responses drain. -
#10502
f665267Thanks @gabedemesa! - FixOpenAiStructuredOutput.toCodecOpenAIandAnthropicStructuredOutput.toCodecAnthropicrejecting optional records and tuples in the format they advertise. -
#10326
2968901Thanks @fubhy! - Construct aTestClockfaster and with less memory inTestClock.makeandTestClock.layer. -
#10318
c0be8f6Thanks @jpowersdev! - Fix SQL-backedPersistedQueuejobs retrying up to a second early on SQLite and MySQL, and remove an extra second of delay from delayed offers on SQLite. -
#10463
d9101fcThanks @effect-bot! - Fix effects hanging whenScheduler.MaxOpsBeforeYieldis set to 1 or 2. -
#10437
871e863Thanks @kiliancs! - Fix defects from a tool handler's interrupt finalizers being discarded when aToolkit.handlestream stops early. -
#10393
6a5d86cThanks @tim-smart! - FixWorkflowEngine.layerMemoryrunningWorkflow.addFinalizerfinalizers before completion when a workflow is resumed after a defect or resumed concurrently. -
#10406
3c9a185Thanks @effect-bot! - Add apositionsoption toXml.decodeandXml.decodeStringthat reports thelineandcolumnof eachStartElement.