Repository navigation
Fix Node HTTP text keeping a UTF-8 BOM that breaks json - #9014
Merged
tim-smart merged 4 commits intoOct 11, 2026
Merged
Conversation
🦋 Changeset detectedLatest commit: 7daaa5c The changes in this PR will be included in the next version bump. This PR includes changesets to release 32 packages
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 |
Contributor
Bundle Size AnalysisGenerated from PR build output; treat the content below as untrusted.
|
Merged
This was referenced Oct 16, 2026
brandhaug
added a commit
to brandhaug/b2b-saas-starter
that referenced
this pull request
Oct 18, 2026
## pnpm-workspace.yaml (default) ## Dependency Updates | Package | From | To | Type | | --- | --- | --- | --- | | `@effect/platform-node` | 4.0.3 | 4.0.5 | patch | | `@effect/sql-d1` | 4.0.3 | 4.0.5 | patch | | `@effect/tsgo` | 0.51.1 | 0.53.0 | minor | | `@effect/vitest` | 4.0.3 | 4.0.5 | patch | | `effect` | 4.0.3 | 4.0.5 | patch | ## Release Notes <details> <summary><b>@<!---->effect/platform-node</b> (4.0.3 → 4.0.5) — 2 releases</summary> <details> <summary><b>4.0.5</b></summary> ### Patch Changes - [#9158](Effect-TS/effect#9158) [`5951ac0`](Effect-TS/effect@5951ac0) Thanks @<!---->fubhy! - Add typed connection options to `NodeHttpClient` for unix sockets and mutual TLS. - [#9136](Effect-TS/effect#9136) [`12be65e`](Effect-TS/effect@12be65e) Thanks @<!---->tim-smart! - Redact sensitive query values in HTTP spans, request inspection and error messages. Also redact URL credentials in client spans, request inspection and errors. Request URLs sent over the wire are unchanged. Move `AWSAccessKeyId`, `Signature`, `sig` and `X-Goog-Signature` from `Headers.CurrentRedactedNames` to the new `UrlParams.CurrentRedactedNames`. A custom list replaces these defaults. Add `UrlParams.isRedactedName`, `UrlParams.redact` and `UrlParams.redactUrl` for explicit redaction. - Updated dependencies [[`f665607`](Effect-TS/effect@f665607), [`dbf442b`](Effect-TS/effect@dbf442b), [`74d1930`](Effect-TS/effect@74d1930), [`a03afb6`](Effect-TS/effect@a03afb6), [`f159284`](Effect-TS/effect@f159284), [`5d301cc`](Effect-TS/effect@5d301cc), [`cd74ea2`](Effect-TS/effect@cd74ea2), [`925cf64`](Effect-TS/effect@925cf64), [`54c51d9`](Effect-TS/effect@54c51d9), [`995c104`](Effect-TS/effect@995c104), [`816575e`](https://github.com/Effect-TS/effect/co …[full notes](https://github.com/Effect-TS/effect/releases/tag/%40effect/platform-node%404.0.5) </details> <details> <summary><b>4.0.4</b></summary> ### Patch Changes - [#9014](Effect-TS/effect#9014) [`95a3ab7`](Effect-TS/effect@95a3ab7) Thanks @<!---->jayhemnani9910! - Ignore a leading UTF-8 BOM when decoding Node HTTP request and response text, so `json` no longer fails on BOM-prefixed bodies. - Updated dependencies [[`7547a99`](Effect-TS/effect@7547a99), [`711719d`](Effect-TS/effect@711719d), [`251f849`](Effect-TS/effect@251f849), [`8f1ea52`](Effect-TS/effect@8f1ea52), [`c93485e`](Effect-TS/effect@c93485e), [`37e088f`](Effect-TS/effect@37e088f), [`9314666`](Effect-TS/effect@9314666), [`a0a26b7`](Effect-TS/effect@a0a26b7), [`cc843ea`](Effect-TS/effect@cc843ea), [`ab90be9`](Effect-TS/effect@ab90be9), [`a59b971`](Effect-TS/effect@a59b971), [`fccf660`](Effect-TS/effect@fccf660), [`1bfd8fd`](Effect-TS/effect@1bfd8fd), [`78e4c43`](Effect-TS/effect@78e4c43), [`fde67a1`](Effect-TS/effect@fde67a1), [`118deef`](Effect-TS/effect@118deef), [`cea74c9`](Effect-TS/effect@cea74c92ac839009c6ba112504 …[full notes](https://github.com/Effect-TS/effect/releases/tag/%40effect/platform-node%404.0.4) </details> </details> <details> <summary><b>@<!---->effect/sql-d1</b> (4.0.3 → 4.0.5) — 2 releases</summary> <details> <summary><b>4.0.5</b></summary> ### Patch Changes - Updated dependencies [[`f665607`](Effect-TS/effect@f665607), [`dbf442b`](Effect-TS/effect@dbf442b), [`74d1930`](Effect-TS/effect@74d1930), [`a03afb6`](Effect-TS/effect@a03afb6), [`f159284`](Effect-TS/effect@f159284), [`5d301cc`](Effect-TS/effect@5d301cc), [`cd74ea2`](Effect-TS/effect@cd74ea2), [`925cf64`](Effect-TS/effect@925cf64), [`54c51d9`](Effect-TS/effect@54c51d9), [`995c104`](Effect-TS/effect@995c104), [`816575e`](Effect-TS/effect@816575e), [`0df6e06`](Effect-TS/effect@0df6e06), [`52a7d3c`](Effect-TS/effect@52a7d3c), [`ec831c3`](Effect-TS/effect@ec831c3), [`3abc63e`](Effect-TS/effect@3abc63e), [`a841b8b`](Effect-TS/effect@a841b8b), [`91efea7`](Effect-TS/effect@91efea7), [`e271997`](Effect-TS/effect@e271997), [`7719bda`](Effect-TS/effect@7719bda), [`563397f`](Effect-TS/effect@563397f …[full notes](https://github.com/Effect-TS/effect/releases/tag/%40effect/sql-d1%404.0.5) </details> <details> <summary><b>4.0.4</b></summary> ### Patch Changes - [#9027](Effect-TS/effect#9027) [`5d88d87`](Effect-TS/effect@5d88d87) Thanks @<!---->tim-smart! - Update repository dependencies to their latest compatible releases. - Updated dependencies [[`7547a99`](Effect-TS/effect@7547a99), [`711719d`](Effect-TS/effect@711719d), [`8f1ea52`](Effect-TS/effect@8f1ea52), [`c93485e`](Effect-TS/effect@c93485e), [`37e088f`](Effect-TS/effect@37e088f), [`9314666`](Effect-TS/effect@9314666), [`a0a26b7`](Effect-TS/effect@a0a26b7), [`cc843ea`](Effect-TS/effect@cc843ea), [`ab90be9`](Effect-TS/effect@ab90be9), [`a59b971`](Effect-TS/effect@a59b971), [`fccf660`](Effect-TS/effect@fccf660), [`1bfd8fd`](Effect-TS/effect@1bfd8fd), [`78e4c43`](Effect-TS/effect@78e4c43), [`fde67a1`](Effect-TS/effect@fde67a1), [`118deef`](Effect-TS/effect@118deef), [`cea74c9`](Effect-TS/effect@cea74c9), [`b7c1ac6`](Effect-TS/effect@b7c1ac6), [`f837966`](https://github.com/Effect-TS/effect/ …[full notes](https://github.com/Effect-TS/effect/releases/tag/%40effect/sql-d1%404.0.4) </details> </details> <details> <summary><b>@<!---->effect/tsgo</b> (0.51.1 → 0.53.0) — 2 releases</summary> <details> <summary><b>0.53.0</b></summary> ### Minor Changes - 13a46c9: The `deterministicKeys` rule and the key completions now compute a key for files without a `package.json`, or whose nearest `package.json` has no `name`. The key is built as usual, but without the package name. The sub-directory segment is relative to the `package.json` directory if one is found, otherwise to the `tsconfig.json` directory, otherwise to the program's common source directory. Projects that enabled `deterministicKeys` without a `package.json` will now see reports. This differs from the upstream `@effect/language-service`, which skips these files. ```json { "name": "@effect/language-service", "keyPatterns": [{ "target": "service", "pattern": "default" }] } ``` ```ts // src/services/AuthService.ts, no package.json, tsconfig.json at the project root // reports: the expected key is `services/AuthService/MyService` export class MyService extends Context.Service<MyService, {}>()("MyService") {} ``` - d8c489b: Add `errorPayloadShadowsName` to detect inline `name` payload fields on Effect error classes. For example, `Data.TaggedError("ToolNotFound")<{ name: string }>` copies the payload's `name` onto the error instance and hides the error type in logs. Rename the field to `toolName`. The rule inspects inline payloads only and allows a field whose value is the literal the error already uses as its name. - 13a46c9: Add an `"identifier"` pattern to `keyPatterns` for the `deterministicKeys` rule. With it, the expected key is the class name alone. ```json { "name": "@effect/language-service", "keyPatterns": [{ "target": "error", "pattern": "identifier" }] } ``` ```ts // reports: the expected key is `KeybindingsConfigError` export class KeybindingsConfigError extends Data.TaggedError("KeybindingsConfigParseError")<{}> {} ``` - b1ed4ba: Add `preferNamespaceImport` and `preferBarrelImport`, two diagnostics that report existing imports that contradict the import style confi …[full notes](https://github.com/Effect-TS/tsgo/releases/tag/%40effect/tsgo%400.53.0) </details> <details> <summary><b>0.52.0</b></summary> ### Minor Changes - 3e4a55d: Route Effect contextual-type queries through `TypeParser.GetContextualType` and enforce the wrapper with customlint. For example, use `tp.GetContextualType(node, checker.ContextFlagsNone)` instead of the checker method. Query behavior stays unchanged, with one place to add contextual-type safety guards in future changes. - 0269634: Add `effectSleepZeroToYieldNow`, a style suggestion with a quick fix for zero-duration `Effect.sleep` calls. For example, `Effect.sleep(0)` becomes `Effect.yieldNow()` in Effect v3 and `Effect.yieldNow` in Effect v4. The rule also recognizes safe zero-duration strings, tuples, and Duration constructors. The replacement yields through the fiber scheduler instead of the Clock service. - 181b2b3: Add the `flatMapToTap` style suggestion and quick fix for Effect v3 and v4. Callbacks that run an effect and restore their unchanged parameter with terminal `Effect.as` or `Effect.map` can use `Effect.tap` instead. The fix preserves callback statements and earlier effect transformations. - 7d051dd: Route internal symbol and type location queries through TypeParser and enforce this with customlint. Reuse the existing TypeParser throughout pipeable signature comparison. Prevent false TS2790 diagnostics for valid index-signature deletes such as `declare const map: { [key: string]: number }; delete map.x;`. Symbol queries skip deleted property accesses and their names, including parenthesized and optional targets. Receiver and computed-key queries remain available, and invalid required-property and readonly deletes still report compiler errors. - f178ff2: Add the opt-in `preferEffectArray` diagnostic in `effectNative` for native Array method calls and references. It suggests 16 corresponding Effect Array APIs and explains migration differences, such as `values.find(predicate)` becoming `Array.findFirst(values, predicate)` with an `Option` result. The rule is disabled by default and enabled as a warning by the …[full notes](https://github.com/Effect-TS/tsgo/releases/tag/%40effect/tsgo%400.52.0) </details> </details> <details> <summary><b>@<!---->effect/vitest</b> (4.0.3 → 4.0.5) — 2 releases</summary> <details> <summary><b>4.0.5</b></summary> ### Patch Changes - Updated dependencies [[`f665607`](Effect-TS/effect@f665607), [`dbf442b`](Effect-TS/effect@dbf442b), [`74d1930`](Effect-TS/effect@74d1930), [`a03afb6`](Effect-TS/effect@a03afb6), [`f159284`](Effect-TS/effect@f159284), [`5d301cc`](Effect-TS/effect@5d301cc), [`cd74ea2`](Effect-TS/effect@cd74ea2), [`925cf64`](Effect-TS/effect@925cf64), [`54c51d9`](Effect-TS/effect@54c51d9), [`995c104`](Effect-TS/effect@995c104), [`816575e`](Effect-TS/effect@816575e), [`0df6e06`](Effect-TS/effect@0df6e06), [`52a7d3c`](Effect-TS/effect@52a7d3c), [`ec831c3`](Effect-TS/effect@ec831c3), [`3abc63e`](Effect-TS/effect@3abc63e), [`a841b8b`](Effect-TS/effect@a841b8b), [`91efea7`](Effect-TS/effect@91efea7), [`e271997`](Effect-TS/effect@e271997), [`7719bda`](Effect-TS/effect@7719bda), [`563397f`](Effect-TS/effect@563397f …[full notes](https://github.com/Effect-TS/effect/releases/tag/%40effect/vitest%404.0.5) </details> <details> <summary><b>4.0.4</b></summary> ### Patch Changes - Updated dependencies [[`7547a99`](Effect-TS/effect@7547a99), [`711719d`](Effect-TS/effect@711719d), [`8f1ea52`](Effect-TS/effect@8f1ea52), [`c93485e`](Effect-TS/effect@c93485e), [`37e088f`](Effect-TS/effect@37e088f), [`9314666`](Effect-TS/effect@9314666), [`a0a26b7`](Effect-TS/effect@a0a26b7), [`cc843ea`](Effect-TS/effect@cc843ea), [`ab90be9`](Effect-TS/effect@ab90be9), [`a59b971`](Effect-TS/effect@a59b971), [`fccf660`](Effect-TS/effect@fccf660), [`1bfd8fd`](Effect-TS/effect@1bfd8fd), [`78e4c43`](Effect-TS/effect@78e4c43), [`fde67a1`](Effect-TS/effect@fde67a1), [`118deef`](Effect-TS/effect@118deef), [`cea74c9`](Effect-TS/effect@cea74c9), [`b7c1ac6`](Effect-TS/effect@b7c1ac6), [`f837966`](Effect-TS/effect@f837966), [`09738f4`](Effect-TS/effect@09738f4), [`22e7129`](Effect-TS/effect@22e7129 …[full notes](https://github.com/Effect-TS/effect/releases/tag/%40effect/vitest%404.0.4) </details> </details> <details> <summary><b>effect</b> (4.0.3 → 4.0.5) — 2 releases</summary> <details> <summary><b>4.0.5</b></summary> ### Patch Changes - [#9055](Effect-TS/effect#9055) [`f665607`](Effect-TS/effect@f665607) Thanks @<!---->Tyagiquamar! - Pass a `NonEmptyArray` to the `onNonEmpty` callback of `Array.match` when the input is a mutable array. - [#9110](Effect-TS/effect#9110) [`dbf442b`](Effect-TS/effect@dbf442b) Thanks @<!---->petar-omni! - Fix `AsyncResult.all` failures carrying a single input's `previousSuccess` instead of the combined record or tuple. - [#9105](Effect-TS/effect#9105) [`74d1930`](Effect-TS/effect@74d1930) Thanks @<!---->tim-smart! - Fix infinite atom rebuilds caused by late reads of uninitialized dependencies. - [#9145](Effect-TS/effect#9145) [`a03afb6`](Effect-TS/effect@a03afb6) Thanks @<!---->jayhemnani9910! - Add `Flag.withOptionalValue` for GNU-style flags with an optional value, like `--color[=WHEN]`. A bare flag uses the given value; an explicit value must be attached with `=`. - [#9131](Effect-TS/effect#9131) [`f159284`](Effect-TS/effect@f159284) Thanks @<!---->tim-smart! - Fix lost deferred callback wakes in cluster workflows when an activity suspends while a parallel activity is still running. - [#9094](Effect-TS/effect#9094) [`5d301cc`](Effect-TS/effect@5d301cc) Thanks @<!---->okxint! - Name cluster entity RPC server spans by entity type only (e.g. `WorkflowEntity.Run`) so span names stay low-cardinality. The entity ID is still recorded in the `entity.id` span attribute. - [#9176](Effect-TS/effect#9176) [`cd74ea2`](Effect-TS/effect@cd74ea211980de0989ec45 …[full notes](https://github.com/Effect-TS/effect/releases/tag/effect%404.0.5) </details> <details> <summary><b>4.0.4</b></summary> ### Patch Changes - [#9030](Effect-TS/effect#9030) [`7547a99`](Effect-TS/effect@7547a99) Thanks @<!---->effect-bot! - Bound sparse array indices in `SchemaGetter.makeTreeRecord`, used by `Schema.fromURLSearchParams` and `Schema.fromFormData`. An indexed container with more than 20 holes is now returned as an object keyed by its index strings instead of a sparse array, and appending after the maximum array index no longer throws. - [#9083](Effect-TS/effect#9083) [`711719d`](Effect-TS/effect@711719d) Thanks @<!---->effect-bot! - Bound import-time stack detection probes to the frames they inspect, restoring the caller's stack trace limit afterward. - [#9041](Effect-TS/effect#9041) [`8f1ea52`](Effect-TS/effect@8f1ea52) Thanks @<!---->tim-smart! - Stop grouped RequestResolvers from retaining batch keys for the lifetime of the resolver. Equal keys are now matched by the pending batch map, so a key is dropped as soon as its batch stops pending, including after interruption. - [#9010](Effect-TS/effect#9010) [`c93485e`](Effect-TS/effect@c93485e) Thanks @<!---->effect-bot! - Support an explicit client `servername` for TLS socket upgrades without changing hostname behavior when omitted. - [#8990](Effect-TS/effect#8990) [`37e088f`](Effect-TS/effect@37e088f) Thanks @<!---->bastiankistner! - Use decoded response aliases in generated HTTP clients. Render bare numbers with a standard leading finite check as `Schema.Finite`, preserving annotations and other checks. - [#8998](Effect-TS/effect#8998) [`9314666`](Effect-TS/effect@93146666ec49cd6831e9c9d5fa0f9 …[full notes](https://github.com/Effect-TS/effect/releases/tag/effect%404.0.4) </details> </details> --- *This PR was auto-generated by [catalog-update-action](https://github.com/brandhaug/catalog-update-action).* Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
laithalsaadoon
added a commit
to memhtml/memhtml
that referenced
this pull request
Oct 20, 2026
Moves the Effect catalog set (`effect`, `@effect/platform-node`, `@effect/platform-node-shared`, `@effect/vitest`) from 4.0.3 to 4.0.5 with no source or test change. One 4.0.4 entry changes what `packages/telemetry` does when tracing is on, so this move was held for a maintainer's decision and merged on it.
What moves:
- `pnpm-workspace.yaml:61-64`: the four catalog lines.
- `pnpm-lock.yaml`: only the four Effect entries and their peer suffixes (10 lines in the peer-stripped table).
- Docs: the 17 mentions of the pin on 15 lines in `docs/architecture/system-overview.md`, `docs/diagrams/structural/dependency-graph.md`, `docs/insights/debugging-guide.md`, `docs/insights/tech-debt.md` and `docs/reference/rpc-tools.md`. Each claim those lines make was re-checked at 4.0.5 (five MCP protocol adapters, `layerStdio`'s `instructions` option, the `@stability unstable` tags, `Schema.Struct({})` and `Tool.EmptyParams` JSON Schemas, `Config.String`). The same lines' citations into `pnpm-workspace.yaml`, `apps/cli/src/head-server.ts` and `CLAUDE.md`, stale since #265 and #287 moved those files, now name the lines they mean. Every edit keeps its cell width.
Behavior that reaches memhtml:
- Effect-TS/effect#9053 (4.0.4), telemetry on only: the OTLP exporter waits for a collector's `Retry-After` between its three retries after a 408 or 5xx, never less than the 1 s it waited before. Measured on this tree against a local collector: arrivals at 0, 2, 4 and 6 s instead of 0, 1, 2 and 3 s for a 503 with `Retry-After: 2`; unchanged without the header.
- Effect-TS/effect#9014 (4.0.4): Node HTTP text decoding drops a leading UTF-8 BOM, so a BOM-prefixed JSON body to the head server's `/v1/search`, `/v1/read`, `/v1/neighbors`, `/v1/commit` or `/v1/rebase` now decodes instead of answering 400. `/v1/exec` parses its body itself and still refuses one. memhtml's own head client never sends a BOM, so its traffic is unchanged.
- Effect-TS/effect#9136 (4.0.5): the values of `sig`, `Signature`, `AWSAccessKeyId` and `X-Goog-Signature` query parameters are redacted in the request line a head-server 400 echoes and, with telemetry on, in server span `url.full` and `url.query`. memhtml's client sends no query string.
- Measured identical on this tree: interrupt merging (#9113), JSON Schema bounds on the two new decode-only schemas (#9081), the MCP server's shared codecs (#9031, 15 tools, identical transcripts), `Duration` conversion (#9109, #9161), and server span timing (#9066).
Verified:
- `mise run check`: 75/75 tasks on this branch.
- A reader compiled all 16 TypeScript packages plus `tests-integration` against the 4.0.5 tarballs with the repo's compiler options (0 errors), with a two-way self-check: a probe using APIs that exist only in 4.0.5 (`UrlParams.redactUrl`, `NodeHttpClient.layerNodeHttpOptions`) fails on 4.0.3 and passes on 4.0.5, and a probe that #9112 breaks passes on 4.0.3 and fails on 4.0.5.
- The unit suites of `packages/session`, `head`, `curator`, `snapshot`, `telemetry`, `store`, `eval`, `apps/cli` and `apps/mcp` pass 1443/1443 on both versions.
Effect 4.0.6 is not published; its "Version Packages" PR (Effect-TS/effect#9197) queues entries on the head server's Node HTTP paths, MCP stdio streams and OTLP serialization, so the next move gets its own read.
Supersedes the Effect members of Dependabot's minor-and-patch group.
This branch is waiting to be deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type
Description
A JSON body that starts with a UTF-8 BOM (
EF BB BF, common in files saved by Windows tools) decodes everywhere except the Node adapters:NodeHttpServer, route returningyield* request.json: 400HttpRouter.toWebHandler(Bun, Deno, web): 200{"a":1}HttpClientreadingresponse.jsonfrom a server that sends that body:FetchHttpClientandNodeHttpClient.layerUndicisucceed,NodeHttpClient.layerNodeHttpfails withDecodeErrorNodeHttpIncomingMessage.textdecodes withBuffer.toString("utf8"), which keeps the BOM, soJSON.parsefails. The result also depends on read order: if a handler readsrequest.arrayBufferfirst, the cached text comes from theTextDecoderset up in thearrayBuffergetter, the BOM is dropped andrequest.jsonsucceeds.The change decodes with
TextDecoderin thetextgetter too, which matches thearrayBufferpath, the Undici and web responses, and the Fetchtext()/json()behaviour. Bytes fromarrayBufferare unchanged.Testing
NodeHttpClient.test.ts:request and response json ignore a leading UTF-8 BOM(fetch, node:http and undici clients against the Node server) fails onmainand passes with the change.Reproduced with
effect@4.0.2and@effect/platform-node@4.0.2, and onmain. After the change the curl request above returns 200 and all three clients decode the response.pnpm vitest run --project @effect/platform-node: 466 passed (main: 463)pnpm lintandtsc -b packages/platform/node/tsconfig.json: passRelated
textonto the cached bytes and kept the BOM-preserving decode)Closes EFF-1981