Patch Changes
-
#6743
ac3485aThanks @IMax153! - Add a scopedCliOutput.Presenterservice for suppressing, redirecting, or replacing built-in CLI help, invalid-invocation, and version output. -
#9873
3a4c691Thanks @effect-bot! - Require tool parameter schema services inResponse.AllParts,Response.PartandResponse.StreamPart, including for toolkits with handlers, and addTool.ParametersDecodingServices. -
#9861
4f0600eThanks @effect-bot! - Add atoModelOutputoption toTool.makeandTool.dynamicfor sending text, images and files to the model in place of the serialized tool result. Anthropic and OpenAI Responses send native content blocks; OpenAI-compatible APIs and OpenRouter send text with a placeholder for each file, via the newPrompt.toolModelOutputToText.OpenAI Responses now sends PDF file parts given as base64, data URL or HTTP(S) URL strings instead of dropping them.
-
#9377
110fd22Thanks @gcanti! - Add aconcurrencyoption toArbitrary.checkEffectand global check configuration to run independent property evaluations concurrently. Results remain deterministic for deterministic generators and repeatable properties, while shrinking and replay stay sequential. The default concurrency is1. -
#9811
aa58cdaThanks @effect-bot! - Speed upBase64.encodeandBase64Url.encodeon large inputs and reduce the memory they allocate. -
#9913
8e257e7Thanks @Marve10s! - Fix duplicate interrupt reasons when interrupting a fiber insideEffect.withSpanorEffect.fn. -
#9846
e62a149Thanks @mkantautas! - FixChildProcessSpawnerhelpers hanging when a command fills a pipe the helper never reads.exitCodenow reads and discardsstdoutandstderruntil the process exits, andstring,lines,streamStringandstreamLinesread and discardstderrunlessincludeStderris set. A failure reading that output while the helper runs, such as from an outputSink, now fails the helper. -
#9794
dcd43a5Thanks @effect-bot! - Clarify thatChildProcessoutput sinks forstdout,stderrand outputadditionalFdsonly receive data while the corresponding handle stream is consumed, and that the handle stream emits the sink's results. -
#9921
3388cddThanks @Marve10s! - Fix Bash completion of file and directory paths containing spaces, quotes or glob characters. -
#9976
81b0e14Thanks @effect-bot! - AddCompletions.fromCommandtoeffect/cli. It converts an existingCommandtree into aCommandDescriptor, so build tooling can generate shell completion scripts withCompletions.generatewithout running the CLI. -
#9881
a046435Thanks @effect-bot! - SkipFlag.withFallbackPromptandArgument.withFallbackPromptfallbacks whenTerminalCapabilities.canPromptisfalse, failing with the originalMissingOptionorMissingArgumenterror instead of rendering a prompt or waiting for input. -
#9922
f6d8968Thanks @Marve10s! - Show command help for invalid global flag values instead of failing with a raw parse error. -
#8349
5741c3aThanks @ArjunCodess! - Add theCliError.userMessageannotation soCommand.runrenders tagged handler errors without wrapping them inCliError.UserError. -
#9959
381d5c6Thanks @baptisteArno! - Record ClickHouse migrations only after they succeed, so a failed migration and the ones after it are retried on the next run. -
#10001
d47478aThanks @tim-smart! - Stop a runner that lost a shard lock from storing the final reply of a persisted request on that shard. Before storing it, the runner refreshes its shard locks and checks that the shard is still among them. If it is not, the request is left for the shard's new owner. -
#10037
383716dThanks @tim-smart! - Release a frozen runner's PostgreSQL advisory shard locks aftershardLockExpiration. On PostgreSQL 14+,SqlRunnerStoragesetsidle_session_timeouton its lock connection, so a runner that stops refreshing loses its locks instead of holding them until the server drops its TCP connection.With advisory locks on PostgreSQL and MySQL,
SqlRunnerStoragerefresh now only confirms locks its current lock session holds. After the lock connection is replaced, shards held by the previous session are reported lost instead of being silently reacquired. -
#9817
46dc30aThanks @effect-bot! - Fix cluster shutdown waiting forentityTerminationTimeoutwhen a workflow is waiting on a persisted activity request that has not started. During runner shutdown the caller is now abandoned so the request replays under the next owner, and a durable caller abandoned this way is left for replay instead of being answered with an interrupt. WithpreemptiveShutdown: false, entities drain before the runner is marked as shutting down, so such a caller still waits forentityTerminationTimeout. -
#9985
3d5c862Thanks @tim-smart! - Fix a cluster workflow replay ignoring a durable deferred completion that is persisted but not yet processed by the new owner. ADurableDeferred.raceAllcould pick a different winner on replay and run the wrong branch. Workflow replays now read the stored completion from the unprocessed request when it has no reply yet. -
#9845
93ebc4fThanks @effect-bot! - FixClusterWorkflowEnginerunning a completed step's compensation twice wheninterruptUnsafeinterrupts a workflow during a running activity. -
#9938
c7b161aThanks @effect-bot! - Fix a forced shard release stalling forever when a child workflow wakes its still-running parent. The wake's cluster abandonment was retried, so it waited on the retired run and blocked the shard from being reacquired. The abandonment now interrupts the wake, so the activation unwinds, the release completes, and the parent is resumed under the next owner. -
#10034
e55945dThanks @jpowersdev! - FixHttpClientRequest.compressBodyreplacing the request's Content-Type with the body's content type. Compression now only updates the Content-Encoding and Content-Length headers. -
#10035
1a53d6aThanks @jpowersdev! - FixHttpMiddleware.compressionsending an uncompressed response whenAccept-Encodingcontains an empty list member, such asgzip,. Empty members are now ignored as RFC 9110 requires. -
#9769
5e25cc9Thanks @Marve10s! - FixEqual.equalsandHash.hashtreating any two same-lengthArrayBuffers as equal.ArrayBufferandSharedArrayBufferare now compared and hashed by their bytes. -
#9799
9503d5cThanks @effect-bot! - FixExit.hasFails,Exit.hasDies,Exit.hasInterrupts, andAsyncResult.isInterruptednarrowing away every failure when they returnfalse. They now returnboolean, like the matchingCausechecks; useExit.isFailureorAsyncResult.isFailureto narrow. -
#10026
13efb72Thanks @tim-smart! - Prevent laterSemaphore.takecalls from overtaking eligible queued requests while preserving mixed-size overtaking. -
#9767
8ca6abbThanks @Marve10s! - FixQueue.offerAll,MutableList.appendAllandMutableList.prependAllkeeping a reference to the caller's array. Changing that array afterward no longer changes the queued values. -
#9982
4a09dd1Thanks @jpowersdev! - FixJsonSchema.toDocumentDraft07emittingenum: [], which the Draft-07 metaschema rejects. An empty enum now becomes anallOfentry that rejects every value. -
#9754
346fc92Thanks @gcanti! - FixSchema.isCapitalizedandSchema.isUncapitalizedaccepting astral letters with the wrong case. -
#9967
20e5ba8Thanks @gcanti! - FixSchema.isULIDto reject values exceeding the 128-bit ULID limit. -
#9878
f4b237eThanks @Hona! - FixEffect.fnstack frames retaining call arguments. A fiber forked inside anEffect.fncall inherits the frame, which kept the arguments of that call and of every traced call above it alive for as long as the fiber ran. -
#9887
1dd08eeThanks @jayhemnani9910! - FixHttpClient.followRedirectsre-encoding the query of theLocationit follows (%20became+,flagbecameflag=, and invalid UTF-8 bytes were replaced with U+FFFD). The redirected request now uses the resolvedLocationURL without rewriting its query. -
#9948
940be42Thanks @chiefcll! - Format values with own getters inFormatter.formatJsonandCause.prettywithoutProxy, so engines that lack it no longer throw aReferenceError. Getter results stay redacted on every engine. -
#10029
37be245Thanks @jpowersdev! - FixHttpStaticServerdroppingContent-Location,Date,ExpiresandVaryfrom 304 responses. -
#9944
563fde0Thanks @effect-bot! - AddHttpApiClient.decodeResponseto decode a raw endpoint response with the endpoint's declared success and error schemas, for example after aresponseMode: "response-only"call. -
#9796
938cecbThanks @effect-bot! - Reject.and..path parameters inHttpApiClientso they cannot change the request path through URL normalization. -
#9869
cf197c1Thanks @sarankumar1325! - Describe undeclared response statuses inHttpApiClienterrors. The reason is still aDecodeError, now with the descriptionundeclared status code, so the message readsDecode: undeclared status code (418 GET ...)instead ofDecode error (418 GET ...). -
#9998
7ca71bbThanks @tim-smart! - MakeHttpApiClientclose the upgraded connection of anHttpApiSchema.Upgradeendpoint when the101response headers fail to decode, instead of leaving it open. -
#10002
1e73219Thanks @tim-smart! - MakeHttpApiClientclose the upgraded connection of anHttpApiSchema.Upgradeendpoint when it is interrupted right after taking the upgrade, before its cleanup was in place. -
#9941
4dd860dThanks @effect-bot! - AllowHttpApiSchema.StreamUint8ArrayandHttpApiSchema.StreamNdjsonto declare a list of content types. The first entry is the default response type, streaming payloads are accepted under every entry, and OpenAPI emits the stream under each one. -
#9855
4d24a11Thanks @effect-bot! - StopHttpClientErrorreasons from exposing request headers, query parameters and bodies when serialized or inspected. TheirtoJSONnow prints the request as its method and redacted URL, and the response as its status, matching the error message. The full request and response remain available through therequestandresponseproperties. -
#9786
6bbc5acThanks @gcanti! - Fix OpenAPI incorrectly marking optional HTTP parameters and headers as nullable. -
#9770
5fd25f4Thanks @Marve10s! - FixHttpRouter.prefixeddropping the leading/from the local URL when only a query string follows the prefix. A handler for/api?x=1now sees/?x=1instead of?x=1, and a router mounted under a prefix no longer returns 404 for/prefix?query. -
#10011
a461561Thanks @tim-smart! - FormatHttpServerErrormessages with only the request path, so query values and URL credentials can't leak into span errors or logs. The full request is still available on the error. -
#9994
832b3c6Thanks @tim-smart! - Redact the URL in the failure thatHttpMiddleware.tracerrecords for 5xx responses when the response ends, so exporters that read the message later no longer see query values that were only redacted during the request. -
#9874
837e906Thanks @john-griffin! - FixHttpApiClientmethod calls insideEffect.allwidening their required services toany, and reading services off a non-streaming method's type givingunknown. -
#9942
cd1f2d4Thanks @effect-bot! - Name both endpoints whenHttpApiBuilder.layerfinds twoHttpApiEndpoints with the same method and path, and document how to declare request variants of one operation as a single endpoint. -
#9751
fb38ce6Thanks @effect-bot! - Allow buffered payloads and typed101response headers onHttpApiSchema.Upgradeendpoints.HttpApiSchema.Upgrade({ protocol, headers })declares101headers, encoded likeWithHeadersheaders. Clients decode them and return{ headers, socket }, and OpenAPI lists them on the101.- Upgrade endpoints can declare buffered payloads. Streaming payloads are still rejected.
- Handlers receive an
upgradefunction instead ofsocket:upgrade(), orupgrade({ headers })when headers are declared. 426 Upgrade Requiredis returned before the payload is decoded.HttpServerRequestgainsupgradeWith({ headers }), andupgradeisupgradeWith({}). Third-partyHttpServerRequestimplementations must add it. WebSocket upgrades fail when headers are given.NodeHttpServerwaits for the request body to end before writing the101. On Node 25 and older, which do not parse upgrade request bodies, it readsContent-Lengthbodies from the connection and answers chunked ones with411 Length Required.NodeMultipartfails with aMultipartErrorwhen its source stream errors, instead of waiting for more input.
-
#9815
446c7acThanks @tim-smart! - Ignoreend,attribute,event, andaddLinkscalls on spans that have already ended. Logs andEffect.annotateCurrentSpanfrom fibers that outlive their span no longer modify the ended span,OtlpTracerno longer exports a span twice whenendis called again,OtelSpanno longer triggers OpenTelemetry SDK warnings for late calls, and the DevTools tracer no longer sends events for ended spans. -
#10024
b48b7d8Thanks @jpowersdev! - Ignore malformed Set-Cookie Max-Age attributes instead of parsing their numeric prefixes. -
#8180
dc66d90Thanks @Ishkirat-Singh! -SchemaRepresentation.fromJsonSchemaDocumentnow supports$refpointers below top-level definitions, including shared and recursive schemas, and rejects circular pointer aliases during import. -
#9999
d5a3dc3Thanks @jpowersdev! -JsonPatch.applynow throws on malformed JSON Pointer escapes, such as/a~2or a trailing~, instead of treating them as literal keys. -
#10027
482e0d5Thanks @tkr109! - FixMatcharray patterns matching arrays shorter than the pattern. -
#8509
d84f518Thanks @IMax153! - Add acontrolMessagesoption to the JSON-RPC serializations inRpcSerialization. MCP servers disable it, so@effect/rpc/*notifications from MCP clients no longer stop stdio servers or write@effect/rpc/Pongto stdout. -
#9961
d34d399Thanks @effect-bot! - FixMcpServermethod-not-found, invalid-params and invalid-request errors including an internal_tagfield. Strict MCP clients such asMcpClientrejected these responses and the stdio transport stopped serving later requests. -
#9886
5bbd25eThanks @jayhemnani9910! - FixMultipartParserrejecting horizontal tabs in quotedContent-DispositionandContent-Typeparameters. -
#9768
14eab6bThanks @Marve10s! -MutableRefandRefnow compare by reference. Distinct instances with equal contents no longer compareEqualor share aHashSetorHashMapkey. -
#9925
af8fcb3Thanks @Marve10s! - FixOpenApi.fromApito require all stacked security middleware instead of documenting them as alternatives. -
#9829
6b82a28Thanks @tim-smart! - Add theeffect/observability/OtlpProxymodule, which serves OTLP routes that forward browser telemetry to a collector or vendor and keep credentials on the server. -
#9914
3043aeaThanks @Marve10s! - FixPartitionedSemaphoredeadlocking when waiters in different partitions request multiple permits, by completing one waiter before rotating to the next partition. -
#9646
785577eThanks @tim-smart! - Add the experimentaleffect/persistence/CircuitBreakermodule with keyed circuits, consecutive and rate trip policies, an in-memory store and a Redis store, plusHttpClient.withCircuitBreakerandHttpClient.circuitBreakerClassifier. -
#9800
a8dbbceThanks @effect-bot! - FixPoolwaiters starving under contention. Capacity freed by a release, an ended reservation, a new acquisition or a strategy reclaim now goes to the longest-waiting borrower instead of a borrower that arrives later. -
#9762
65094acThanks @godu! - FixStream.broadcastNdropping the last element for a subscriber that keeps up while another lags beyond capacity.PubSub.endno longer drops a backpressured message that a waiting subscriber has not received yet. -
#9903
113ec70Thanks @jayhemnani9910! - Redact the AWS SigV4 query parametersX-Amz-Signature,X-Amz-CredentialandX-Amz-Security-Tokenby default. -
#10032
ad3126eThanks @jpowersdev! - FixHttpClient.followRedirectskeepingContent-Encoding,Content-LanguageandContent-Locationheaders on redirects that switch the request to GET. -
#10036
eedfb27Thanks @effect-bot! - Release discarded redirect response bodies inHttpClient.followRedirects. -
#9828
45c467aThanks @tim-smart! - AddRedis.reserve, which leases a dedicated connection from a pool, so blocking commands likeXREAD BLOCKandBLPOPno longer hold up other commands on the shared connection.NodeRedis,BunRedisandDenoRedislayers acceptmaxConnections,minConnections,idleTimeoutandacquireTimeoutto size the pool.Redis.makenow requires aconnectoption, and hand-writtenRedisservices need areservemember. -
#9872
c983fc1Thanks @effect-bot! - Reject repeated occurrences of single-valued CLI flags instead of silently keeping the first value. UseFlag.atLeast,Flag.atMostorFlag.betweento accept multiple values. -
#9900
58f164fThanks @effect-bot! - FixRpcClientscope closure hanging when a streamed chunk fails to decode while the socket disconnects and never reconnects. The best-effortInterruptsent to the server for the failed request no longer blocks client shutdown, and is still sent if the client stays open. -
#9899
f6df1aaThanks @effect-bot! - Treat synchronous throws from RPC handlers as request-level defects, sodisableFatalDefects: truefails only the throwing request instead of every pending request on the client. -
#9931
c05355cThanks @Marve10s! - FixRpcSerialization.jsonRpcandndJsonRpcdropping or reordering stream chunks when a stream request is sent in a JSON-RPC batch. -
#9898
ae7805cThanks @effect-bot! - Add adisableFatalDefectsoption toRpcTest.makeClient, so a handler defect fails only its own request instead of every pending request on the client. -
#9917
9ffc621Thanks @Marve10s! - FixSchedule.fibonacciskipping the repeated initial delay. For a base of 100 millis the delays are now 100, 100, 200, 300, 500 ms instead of 100, 200, 300, 500, 800 ms, so every retry delay after the first is shorter than before. -
#9771
c97b331Thanks @Marve10s! - FixSchemaRepresentation.toCodeDocumentgenerating code that fails to load when a schema identifier isSchema,RegExp,DateorSymbol. -
#9613
15297e5Thanks @gcanti! - Restore encoded content schemas forSchema.fromJsonStringin schema representations and JSON Schema, including SSE event data in OpenAPI.Schema.fromJsonStringnow ignores explicitcontentMediaTypeandcontentSchemaannotations on its encoded String. PlainSchema.Stringschemas still honor those annotations.Content declarations and checks now participate in code generation and persistence; add any missing
toCodecallbacks orrepresentationidentities.The encoded projection of
Schema.fromJsonStringno longer carries acontentMediaTypeannotation. -
#9970
41f6738Thanks @danieljvdm! - Keep caller stack frames in errors created withSchema.Error.makeandSchema.TaggedError.make, including when only a decoder is registered. -
#9620
53f9352Thanks @Marve10s! - SupportSchema.Enumkeys inSchema.Record, declaring each enum member value as a required property instead of throwing during construction. -
#9864
b72f6a2Thanks @gcanti! -Schema.Recordnow consistently rejects optional index-signature values created withSchema.optionalKeyorSchema.optional. UseSchema.UndefinedOrto allowundefinedvalues. -
#9775
52e1716Thanks @gcanti! - Preserve shared references inSchema.toCodecJsonandSchema.toCodecStringTree, and retainhttpApiStatusannotations when adding checks.If you relied on checks clearing HTTP statuses, add
.annotate({ httpApiStatus: undefined })explicitly. -
#9850
50c863aThanks @gcanti! - FixSchema.toJsonSchemaDocumentthrowing for named template-literal segments and emitting incorrect schemas for segment checks, exclusive unions, and empty unions. -
#9929
c148d27Thanks @Marve10s! - FixSnowflake.makeGeneratorreturning duplicate ids when the clock is frozen or moves backward. -
#9758
a11ecddThanks @bezff! - FixIN ${sql.in([])}compiling to the invalidIN (). An empty list now matches no rows withINand every row withNOT IN, when the keyword directly precedes the helper. On PostgreSQL, array-typed columns are not supported, and a comparison on the left ofINmust be parenthesized:a = (b IN ${sql.in([])}). -
#10014
08e338eThanks @effect-bot! - SplitSqlEventJournalbatch statements so large remote syncs andwriteManycalls stay within database parameter limits, including the 100 parameters Durable Object SQLite allows per statement, still committing each batch in one transaction after a single callback. -
#9951
8450ad5Thanks @tim-smart! - KeepSqlResolverbatches separated by transactions started withSqlClient.makeWithTransactionwhen the caller's context has noSqlClient, or carries a different client. Requests outside such a transaction no longer join its batch, where a rollback could discard their writes. -
#9825
39da87aThanks @MaxFreedomPollard! - FixtransformResultNamesandtransformQueryNamesthrowing on JSON arrays that containnull, and turning scalar items in those arrays into objects. -
#9759
a2adb31Thanks @bezff! - Escape thesql.updateValuesalias as an identifier, without applying name transforms. Pass a bare alias rather than pre-quoted SQL, and quote mixed-case PostgreSQL aliases where they are referenced. CustomonRecordUpdatecompiler hooks now receive the alias already escaped. -
#9989
a6174d5Thanks @jpowersdev! - FixSse.makeParserdropping the first event of a stream that starts with a UTF-8 BOM when an empty chunk is fed first. -
#9772
96e6004Thanks @MichaelDeBoey! - Add the root$schemato thedraft-07anddraft-2020-12schemas returned bySchema.toStandardJSONSchemaV1. -
#9915
3ebd645Thanks @Marve10s! - FixStream.groupByandStream.groupByKeygroups not ending when the upstream ends or fails. -
#9916
3c3c79bThanks @Marve10s! - FixStream.groupedandStream.rechunkdropping buffered elements when the upstream fails. -
#9803
8c6d2faThanks @effect-bot! - Keep upstream stream failures out of sink error handlers inStream.run,Stream.peelandStream.aggregate/Stream.aggregateWithin. Upstream failures now reach the caller unchanged instead of being remapped or recovered bySink.mapError,Sink.catch,Sink.catchCauseorSink.orElse, andSink.onExitobserves them as an interruption. -
#9954
1ff35d2Thanks @effect-bot! - Preserve the throw location of defects raised inEffect.syncandEffect.suspendwhen rendering causes on V8. -
#9834
2b100e9Thanks @effect-bot! - Emit smaller declarations for exportedData.taggedEnumconstructors by returning the namedData.TaggedEnum.Constructorand newData.TaggedEnum.GenericConstructortypes instead of expanded anonymous objects.Libraries that export a generic tagged enum and are built against this version emit
Data.TaggedEnum.GenericConstructorin their declarations, so their consumers needeffect4.0.7 or later. -
#10023
e3938e5Thanks @jpowersdev! - FixCookies.fromSetCookiedropping cookies with spaces or tabs before=, such assession = abc, and keeping that whitespace at the start of the value insession= abc. Spaces and tabs around the name and value are now removed, as RFC 6265 requires, while percent-encoded spaces in the value are still decoded. -
#10028
f90101aThanks @jpowersdev! - FixHttpStaticServerignoringIf-MatchandIf-Unmodified-Since. Failed preconditions now return 412 before cache validation and range handling. -
#10022
306c9a1Thanks @jpowersdev! - FixToml.parsetreating everything after a bare carriage return as comment text. A carriage return not followed by a line feed now throws aSyntaxError; LF and CRLF line endings are still accepted. -
#10021
5b69c67Thanks @jpowersdev! - FixToml.parseto reject forbidden raw control characters, including bare carriage returns. -
#10019
a12ffe3Thanks @jpowersdev! - FixToml.parseto reject integers outside JavaScript's safe integer range instead of silently rounding them. -
#9904
f6cf0fdThanks @FredAmartey! - FixToml.parseaccepting a table defined twice, such as a[table]header for a table that dotted keys already defined. -
#9924
3541f65Thanks @Marve10s! - FixToml.parseto reject Unicode escapes that are not scalar values, as required by TOML 1.0. -
#10025
d50aaa2Thanks @jpowersdev! - FixCookies.parseHeaderleaving quotes on values surrounded by whitespace. -
#10013
3731ddbThanks @tim-smart! - FixSqlRunnerStorageleaking shard locks on Vitess after releasing all shards.RELEASE_ALL_LOCKS()makes vtgate replace the session's lock connection, so the stored lock holder id went stale: later acquisitions took locks the runner already held a second time, and releasing such a shard left it locked. The storage now re-takes its pin lock after releasing all shards and refreshes the stored id. -
#9835
3b8090cThanks @tim-smart! - EnforceMaxBodySizeon buffered body reads (arrayBuffer,text,json,urlParamsBody) of webHttpServerRequests, as used by Bun, Deno andtoWebHandler. Bodies over the limit fail with aBodyTooLargeRequestParseError, which responds with 413. -
#9986
137757aThanks @tim-smart! - Replay a workflow on the next runner when shutdown interrupts an activity in aDurableDeferred.raceAllwhose other branches are parked. Before, the run was stored asSuspendedand never resumed. -
#9848
a658477Thanks @tim-smart! - Preserve the app's error and service types when applyingHttpMiddleware.xForwardedHeaders, instead of widening them toany.