Small fixes

A selection of 80 fixes from 174 pull requests.

1.BigInt precision

The autofix converted 9007199254740993n through a Number, rounding it to 9007199254740992n. Quoting the digits preserves the original value.

2.The wrong database

A query through client B could borrow client A’s active transaction and hit database A. Each client now has its own transaction-context key.

3.Lost leftovers

Take one item, then zero, then collect: [1, 2, 3] followed by [4, 5] left only [4, 5]. The continuation must retain the unread 2 and 3.

4.Binary data, decoded twice

Merely selecting the text reader made a later binary read return decoded, re-encoded UTF-8. Text must derive from cached bytes, not replace them.

5.Literal configuration values

String.replace interpreted $& in an environment value as a replacement instruction. A callback inserts the value literally, avoiding incorrect expansion and recursion.

6.Partial writes

A successful file write may accept only some bytes. The logger ignored that count and lost the remainder. writeAll completes the batch.

7.Cleanup after a throw

The use callback ran before its cleanup handler was installed. If it threw while constructing an Effect, release was skipped. Suspending the callback fixes the order.

8.Deleting a prefix

Removing “abc” also erased the value stored at “ab”. A trie node is empty only when it has neither children nor a value.

9.Pipeline input

Writing to a pipeline entered its last process, bypassing earlier stages. Input belongs to the first process; output belongs to the last.

10.A counter shared across registries

A metric kept updating its first registry even after another was provided. Cache the metric’s hooks per registry, not once per metric.

11.Request zero

A truthiness check discarded valid request IDs 0 and "". Acknowledgements and interrupts must check for absence, not falsiness.

12.A zero cache lifetime

timeToLive: 0 was treated as omitted, allowing the registry’s nonzero default to retain old results. Only undefined should mean “use the default”.

13.An exhausted comparison

The first comparison consumed an iterator of ordering rules. The second saw no rules and returned equality. Materialize the finite rules once.

14.Iterables are not arrays

A handler could return a generator, but the resolver looped over .length and indexed its results. No requests completed. for…of honors the declared Iterable contract.

15.An error wrapped as an error

A handler’s “missing” error reached callers as a Cause object. Completing with failCause preserves the original failure instead of wrapping its description as a new error.

16.Day 5 became day 15

Type 1, Tab, 5 in an MM-DD prompt: the month’s digit carried into the day. Tab must clear the input buffer, as Left and Right already do.

17.Negative flag values

The wizard turned -2 into a separate option token. Generating --offset=-2 instead of --offset -2 delivers the value to the handler.

18.A suppressed React update

Switch refs from 0 to 1, then set the new ref to 0: React ignored the notification because its stored state was already 0. Count notifications instead.

19.Writing to the wrapper

A fallback atom reused its primary’s writer with the wrong context. setSelf updated the wrapper. Forwarding through the registry gives the primary its own context.

20.A stale tool schema

Replacing a tool’s parameters left its original JSON Schema override intact. It still advertised “query” while expecting “count”. Clear the override on replacement.

21.A bodyless response

A streaming HEAD response handed cleanup to its body stream, then omitted the body. Keeping HEAD on the normal cleanup path closes the request scope.

22.A raw streaming body

Node requires duplex: "half" for a ReadableStream request body. The adapter checked the wrapper’s tag, missing raw streams. Check the outgoing body itself.

23.A missing URL prefix

Combining base /v1 with endpoint /items produced /items. URL resolution replaced the base path. Use the same prefix joining as the generated client.

24.Unparsed form data

The client passed form-urlencoded text to a schema expecting UrlParams. Parse the text before decoding the record.

25.A missing content length

Converting a Web Response to a stream erased its valid Content-Length. Carry the parsed length into the stream’s metadata.

26.Overwriting Vary

CORS replaced Vary: Accept-Language with Vary: Origin, erasing a cache constraint. Merge the dimensions; preserve Vary: * unchanged.

27.The string “null”

sql.json("null") returned null, and sql.json("hello") failed to parse. PGlite treated strings as JSON source. Encode string values before binding.

28.An uncaught SQL error

Uncached statement preparation ran outside Effect’s error capture. Its errors became defects rather than SqlError. Use the same preparation helper as the cached path.

29.The wrong column names

Later SQL statements reused the first statement’s column names, mislabeling rows and losing values. Return matching column names for each row.

30.An index is not a primary key

On an IndexedDB secondary-index cursor, key is the index value. Reconstructing a row’s identity requires primaryKey.

31.Characters are not bytes

“€” counted as one unit against a byte watermark, although its UTF-8 encoding occupies three bytes. Measure the encoded payload.

32.Mixed line endings

An SSE event containing both CRLF and LF could disappear. The line scan must start at the current buffer position plus the retained partial-line offset.

33.A missing first character

The binary codec consumed a leading U+FEFF as a byte-order marker. ignoreBOM: true preserves it as part of the original string.

34.A percent sign in a reference

The definition Rate% exported as #/$defs/Rate%, an invalid URI escape. JSON Pointer escaping must be followed by URI-fragment escaping.

35.Too many arguments

Buffering 200,000 elements with push(...arr) exceeded the engine’s call-argument limit. Append them individually instead.

36.The excluded endpoint

A draw below 1 can still round to 20 in a [10, 20) range. If that happens, return the upper bound’s nearest representable predecessor.

37.Cancelling the existing task

Re-registering the same fiber with onlyIfMissing interrupted it. Check identity before rejecting a new candidate.

38.An evaluator returning itself

Effectable.Class returned its own instance to the interpreter, repeating forever. Delegate to the subclass’s asEffect() instead.

39.Writing zero bytes

An empty buffer produced zero bytes of progress and was classified as a stalled write. It is already complete; return before entering the loop.

40.Attribute order

The same metric labels in a different insertion order created a second series. Sort a fresh entries array before building the key.

41.Child tables in separate entries

Two [[servers]] entries could not each declare [servers.tls]: their identical paths looked like a duplicate. Track the resolved table object, not the textual path.

42.Folded YAML paragraphs

YAML folding added an extra paragraph newline and turned breaks around indented passages into spaces. Track blank lines and indentation when choosing each separator.

43.Optional alternative flags

Flag.optional rejected Flag.orElse trees before parsing. An unused single-leaf assertion was the only obstacle; removing it lets the existing parser handle alternatives.

44.Range on a HEAD request

A HEAD request with an unsatisfiable Range returned 416. Range applies only to GET; HEAD should return the full metadata without a body.

45.Errors during finalization

A writable’s _final error left the sink waiting for a finish event that would never arrive. Keep the error listener active through finalization.

46.An unsupported form reader

The adapter called an unimplemented Undici formData() method. Parse the cached bytes with native Response.formData(), preserving headers for multipart boundaries.

47.A discarded domain option

The MSSQL adapter accepted an NTLM domain but never passed it to the driver. Forward the field with the other authentication options.

48.Binding byte arrays

The driver rejected automatically bound byte arrays because its binary validator expected a Buffer. Adapt the array while preserving its byte offset and length.

49.A replaced reason phrase

Custom statusText, including an empty string, disappeared on the way to Node. Pass it through every writeHead call instead of letting Node substitute its default.

50.An ignored SSL override

A URL with sslmode=prefer was rejected before an explicit ssl option could override it. Permit that mode when the caller has already made the SSL choice.

51.Text from a binary response

XHR forbids responseText in arraybuffer mode. Decode the returned bytes for text and JSON, and pass them directly to stream readers.

52.A stale Vue snapshot

Switching from a ref containing 1 to one containing 10 still displayed 1 until another write. Subscribe to the new ref, then publish its current value.

53.Negative counter deltas

Updates [5, -2, 4] exported as [5, 3, 4]: a legitimate decrease was mistaken for a reset. Apply reset correction only to incremental counters.

54.A field that would not delete

Replacing an optional focused field with an empty object restored its old value. Preserve only fields outside the focus before merging the replacement.

55.An array hole instead of removal

Deleting tuple key "1" left [1, <hole>, 3], while numeric key 1 produced [1, 3]. Canonical string indices must use splice too.

56.An array-valued element

ArrayEnsure confused a single tuple with the outer array. Preserve which branch decoded the input, so [1, 2] becomes [[1, 2]] and round-trips correctly.

57.Waiting past a line ending

A chunk ending in CR already contained a complete line, but the parser pulled again and could encounter an unrelated failure. Emit immediately; only suppress a following LF.

58.Three rows became four

A query with limit(3) and chunkSize: 2 returned four rows. Each continuation must request only the remaining number of rows.

59.An off-by-one allocation

The exclusion scan stopped before reaching ring index zero. One node could receive every shard while the other stayed unused. Include the final search radius.

60.Half a Unicode character

Parsing echo \u{1F600} tail split the emoji and corrupted the next argument. An astral character occupies two UTF-16 units; advance the cooked cursor accordingly.

61.Media-type parameters

text/html; charset=utf-8 had no known extensions, although text/html worked. Strip parameters and whitespace before looking up the media type.

62.A default that never applied

An omitted variadic argument was classified as invalid, so its default never applied. Zero values means missing; a partially supplied list below the minimum remains invalid.

63.One slash too many

A route matched under /api/, then exposed users instead of /users to its handler. Prefix removal must use the same trailing-slash normalization as registration.

64.Stale response metadata

An unannotated replacement body inherited the source’s 429 and text encoding instead of the error defaults 500 and JSON. Writing undefined annotations clears the stale values.

65.Two encoders, two statuses

A stream inside WithHeaders could use a different status from its header encoder and defect. Both encoders must resolve the status from the original wrapped schema.

66.Missing response hooks in tests

The in-memory HTTP client skipped registered pre-response handlers. Headers and cookies added by those hooks disappeared. Run the chain before converting the response.

67.An uncatchable storage error

Durable Object SQL streams exposed native storage errors as defects instead of SqlError. Classify driver failures before row transformations, leaving user-code defects alone.

68.Cleaning up the same key twice

A repeated query key made cleanup access a handler set already deleted by its first occurrence. Skip registrations that are no longer present.

69.Encoding the wrong result branch

A known tool failure could be encoded by an overlapping success schema. Select the encoder using isFailure, rather than asking a success-first union to choose again.

70.A missing semicolon

A generated doctest assertion could swallow the following array expression or IIFE as a continuation of its call. Terminate the generated statement.

71.Overlapping metric intervals

Delta values covered the latest interval, but their timestamps kept the first interval’s start. Use the previous collection time for each new delta point.

72.Normalizing a value twice

The normalized reason tool-calls was decoded again as if it were wire-format tool_calls, producing unknown and leaving calls unflushed. Assign the normalized value directly.

73.An undefined write flag

Forwarding { flag: undefined } erased the file sink’s write default. Spread the options first, then apply flag ?? "w".

74.The wrong address kind

A Unix-domain server reported a TCP address, yielding http://undefined:undefined. Report its Unix socket path instead.

75.A reply without its envelope

sendUnsafe({ value: 42 }) reached the parent as undefined. Both public reply methods must add the data envelope expected by the parent decoder.

76.A URI matched as a path

An HTTPS resource template retained its origin during registration but lost it during lookup. Prefix both inputs with / so the router treats the full URI consistently.

77.A colliding SQL alias

A joined reply_id overwrote an acknowledgement’s own reply ID. Use the distinct reply_reply_id alias expected by the shared decoder.

78.A zero durability threshold

An explicit inMemoryThreshold: 0 became the 60-second default, keeping positive sleeps in memory. Only undefined should select that default.

79.A cause that looked absent

Error causes such as 0, false and an empty string disappeared from diagnostic output. Test whether the cause is defined, not whether it is truthy.

80.A port that never started

A MessagePort listener alone does not deliver queued messages. Call start() after registration so the SQLite client receives readiness and its worker receives requests.

1. BigInt precision2. The wrong database3. Lost leftovers4. Binary data, decoded twice5. Literal configuration values6. Partial writes7. Cleanup after a throw8. Deleting a prefix9. Pipeline input10. A counter shared across registries11. Request zero12. A zero cache lifetime13. An exhausted comparison14. Iterables are not arrays15. An error wrapped as an error16. Day 5 became day 1517. Negative flag values18. A suppressed React update19. Writing to the wrapper20. A stale tool schema21. A bodyless response22. A raw streaming body23. A missing URL prefix24. Unparsed form data25. A missing content length26. Overwriting Vary27. The string “null”28. An uncaught SQL error29. The wrong column names30. An index is not a primary key31. Characters are not bytes32. Mixed line endings33. A missing first character34. A percent sign in a reference35. Too many arguments36. The excluded endpoint37. Cancelling the existing task38. An evaluator returning itself39. Writing zero bytes40. Attribute order41. Child tables in separate entries42. Folded YAML paragraphs43. Optional alternative flags44. Range on a HEAD request45. Errors during finalization46. An unsupported form reader47. A discarded domain option48. Binding byte arrays49. A replaced reason phrase50. An ignored SSL override51. Text from a binary response52. A stale Vue snapshot53. Negative counter deltas54. A field that would not delete55. An array hole instead of removal56. An array-valued element57. Waiting past a line ending58. Three rows became four59. An off-by-one allocation60. Half a Unicode character61. Media-type parameters62. A default that never applied63. One slash too many64. Stale response metadata65. Two encoders, two statuses66. Missing response hooks in tests67. An uncatchable storage error68. Cleaning up the same key twice69. Encoding the wrong result branch70. A missing semicolon71. Overlapping metric intervals72. Normalizing a value twice73. An undefined write flag74. The wrong address kind75. A reply without its envelope76. A URI matched as a path77. A colliding SQL alias78. A zero durability threshold79. A cause that looked absent80. A port that never started