Skip to content

Bump the nuget group with 14 updates - #1364

Merged
nojaf merged 1 commit into
mainfrom
dependabot/nuget/dot-config/nuget-e3fe9c464e
Oct 22, 2026
Merged

nojaf merged 1 commit into
mainfrom
dependabot/nuget/dot-config/nuget-e3fe9c464e

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 22, 2026

Copy link
Copy Markdown
Contributor

Updated fantomas from 8.0.4 to 8.1.0.

Release notes

Sourced from fantomas's releases.

8.1.0

8.1.0 Umbra - 21-10-2026

Changed

  • Multiline tuple type after a cast or type annotation operator goes one level in. #​3561
  • Line comment lined up with the first element of its container stays with the elements. #​3561

Fixed

  • Parenthesized function type gets an extra indent level where no outer function type needs it. #​3554
  • Multiline tuple in the middle of a function type gives invalid code. #​3556
  • Parenthesized function type after an arrow gives invalid code with indent_size 2. #​3557
  • Long type test with :? gives invalid code. #​3558
  • Line comment after the opening parenthesis of a type moves and breaks the type. #​3559
  • Comment between a match pattern and its when guard gives invalid code. #​3560
  • Regression: Stroustrup bracket style in anonymous record type parameter is not respected. #​3069
  • Space inserted before final > in type parameter. #​2860

Special thanks to @​mmabdpr and @​nojaf!

https://www.nuget.org/packages/fantomas/8.1.0

8.0.10

8.0.10

Fixed

  • Comment after a property accessor is lost. #​3527

Special thanks to @​nojaf!

https://www.nuget.org/packages/fantomas/8.0.10

8.0.9

8.0.9

Fixed

  • Comment before a let in the right-hand side of an infix operator is lost. #​3522

Special thanks to @​nojaf!

https://www.nuget.org/packages/fantomas/8.0.9

8.0.8

8.0.8

Changed

  • Update FCS to 'Add range of the when keyword to SynMatchClauseTrivia', commit 409c7a62ea193ec060e87ccad78636feeb0883f1 #​3531

Fixed

  • Comment after 'when' on its own line is lost. The syntax tree had no range for the when keyword of a match clause, so a comment after it had no node on its line to attach to. The parser now records that range, and the comment stays after the keyword. #​3521

Special thanks to @​nojaf!

https://www.nuget.org/packages/fantomas/8.0.8

8.0.7

8.0.7

Fixed

  • Exception abbreviation loses its right-hand side. #​3511
  • Static optimization when ^T struct loses struct. #​3514
  • Static optimization loses the and between its conditions, and reverses its conditions and when clauses. #​3516
  • static extern inside a type loses static. #​3515

Special thanks to @​nojaf!

https://www.nuget.org/packages/fantomas/8.0.7

8.0.6

8.0.6

Changed

  • Update FCS to 'Record the range of the of keyword in SynUnionCaseTrivia', commit 5e9647f158fe282462aba57ed83ada910a91b90e #​3502

Fixed

  • Wrong change of comment's position. The syntax tree had no range for the of keyword of a union case or exception, so a block comment after it, as in exception E of (*name*) string, was attached to the case name and printed in front of of. The parser now records that range, and the comment stays after the keyword. #​1959
  • Cursor is lost when placed on if, then or else if keywords. The cursor now keeps its place on if, elif, else if, then, match, match! and with. #​3387
  • Cursor is lost when placed on the closing bracket of a multiline list or array in the cramped style. #​3506

Special thanks to @​knocte, @​mmabdpr and @​nojaf!

https://www.nuget.org/packages/fantomas/8.0.6

8.0.5

8.0.5

Changed

  • Improved formatting performance. Formatting the source files of dotnet/fsharp allocates around 40% less memory and is roughly 1.4 times faster than 8.0.4, depending on hardware. The fields of WriterEvent, returned by CodeFormatter.GetWriterEventsAsync, are renamed so that cases share them: text for the strings, amount for IndentBy and UnIndentBy, column for the indent and column cases, and nodeType and range for NodeEnd. #​3499
  • Update FCS to 'Record the range of the exceptionin SynExceptionDefnRepr', commit 349d6aaf1e4685a72e43b7f4a0708205e4104b4c #​3500

Fixed

  • Comment between doc comment and exception keyword gets shifted. The syntax tree had no range for the exception keyword, so a comment between the XML doc or attributes and the keyword was placed in front of the exception name, after the keyword. The parser now records that range, and the comment stays in front of the keyword. #​3483

Special thanks to @​nojaf!

https://www.nuget.org/packages/fantomas/8.0.5

Commits viewable in compare view.

Updated fsharp-analyzers from 0.39.2 to 0.41.0.

Release notes

Sourced from fsharp-analyzers's releases.

0.41.0

0.41.0

Added

  • A run where a project or script does not type check no longer looks clean outside the log. The SARIF report lists every type error as a toolExecutionNotifications entry and sets executionSuccessful to false. Pass --fail-on-type-errors to also exit with code -5 (TypeCheckFailed) in that case. The switch is opt-in, so a run that analyzes before building keeps its exit code. A #load or #r in a script that cannot be resolved counts as a type error too.

Changed

  • Breaking: Client.RunAnalyzersSafely is now Client.RunAnalyzers, and the old Client.RunAnalyzers, which only returned the messages, is gone. It hid an analyzer that threw in the log, so a caller could not tell its messages were missing. RunAnalyzers returns an AnalysisResult per analyzer and does not throw. To get only the messages, collect the Ok outputs.
  • Breaking: AnalysisResult.Output is now Result<AnalyzerMessage list, exn> instead of Result<Message list, exn>, so a caller keeps the name, help link and short description of the analyzer behind each message. Read .Message on each item to get the Message as before.
  • An error from loading a script, such as a #load that cannot be resolved, is no longer logged at error level as Script ... has a diagnostic. It is logged with the type errors, as a warning under did not type check, and each type error now names its file and error code. A warning from loading a script is still logged as Script ... has a diagnostic, but at warning level instead of error level.

Fixed

  • File paths in the SARIF report and in --output-format github are relative to the code root. Without a trailing separator on --code-root (or the current directory, its default), every path started with the name of the code root directory, such as repo/src/A.fs instead of src/A.fs. A code root with a trailing separator is unaffected. GitHub code scanning re-creates open alerts once at the corrected paths, because it ties an alert to its file path.
  • --warnaserror, which TreatWarningsAsErrors passes to the compiler, is ignored when type checking for the analyzers, so a warning no longer counts as a type error.
  • An analyzer that throws no longer crashes the CLI. Its exception is logged, the other analyzers keep their messages, the SARIF report lists the failure as a toolExecutionNotifications entry with executionSuccessful set to false, and the CLI exits with -4 (AnalysisAborted). Previously the run stopped with exit code 22, without a SARIF report and without the messages of the other analyzers.
  • An analyzer written as a function that throws before it returns its Async now reports its own exception, instead of a TargetInvocationException with the message Exception has been thrown by the target of an invocation.

Special thanks to @​nojaf!

https://www.nuget.org/packages/FSharp.Analyzers.SDK/0.41.0
https://www.nuget.org/packages/FSharp.Analyzers.SDK.Testing/0.41.0
https://www.nuget.org/packages/fsharp-analyzers/0.41.0

0.40.0

0.40.0

Changed

  • Breaking: Update FSharp.Compiler.Service to 43.12.402 and FSharp.Core to 10.1.402. FSharp.Compiler.Service is not binary compatible between releases, so analyzers built against 0.39 need to be rebuilt.
  • FSharp.Compiler.Service is now pinned to an exact version, like FSharp.Core already was. NuGet now warns (NU1608) when an analyzer project resolves a newer FSharp.Compiler.Service than the SDK was built with, instead of accepting it silently.

Fixed

  • InlineAnnotation is AlwaysInline again for inline values from assemblies built with F# 4.7 or older (dotnet/fsharp#​20260).
  • An analyzer assembly with a dependency that cannot be loaded, such as a newer FSharp.Compiler.Service than the tool ships, is now skipped with an error. Previously the FileNotFoundException crashed the run and no analyzer ran at all.

https://www.nuget.org/packages/FSharp.Analyzers.SDK/0.40.0
https://www.nuget.org/packages/FSharp.Analyzers.SDK.Testing/0.40.0
https://www.nuget.org/packages/fsharp-analyzers/0.40.0

Commits viewable in compare view.

Updated FSharp.Compiler.Service from 43.12.401 to 43.12.402.

Release notes

Sourced from FSharp.Compiler.Service's releases.

No release notes found for this version range.

Commits viewable in compare view.

Updated FSharp.Core from 10.1.401 to 10.1.402.

Release notes

Sourced from FSharp.Core's releases.

No release notes found for this version range.

Commits viewable in compare view.

Updated FsUnit from 7.1.1 to 8.0.0.

Release notes

Sourced from FsUnit's releases.

8.0.0

What's Changed

New Contributors

Full Changelog: fsprojects/FsUnit@7.1.1...v8.0.0

Commits viewable in compare view.

Updated G-Research.FSharp.Analyzers from 0.25.0 to 0.26.0.

Release notes

Sourced from G-Research.FSharp.Analyzers's releases.

0.26.0

0.26.0

Changed

  • Update FSharp.Analyzers.SDK to 0.41.0. #​121

https://www.nuget.org/packages/G-Research.FSharp.Analyzers/0.26.0

Commits viewable in compare view.

Updated Ionide.Analyzers from 0.19.0 to 0.20.0.

Release notes

Sourced from Ionide.Analyzers's releases.

0.20.0

0.20.0

Changed

  • Update FSharp.Analyzers.SDK to 0.41.0, FSharp.Compiler.Service to 43.12.402, and FSharp.Core to 10.1.402. Checkout the release notes for details. #​214

Special thanks to @​nojaf!

https://www.nuget.org/packages/Ionide.Analyzers/0.20.0

Commits viewable in compare view.

Updated Ionide.ProjInfo from 0.75.0 to 0.75.3.

Release notes

Sourced from Ionide.ProjInfo's releases.

0.75.3

Fixed

0.75.2

Changed

0.75.1

Fixed

Commits viewable in compare view.

Updated Microsoft.Extensions.Logging.Abstractions from 10.0.12 to 10.0.13.

Release notes

Sourced from Microsoft.Extensions.Logging.Abstractions's releases.

No release notes found for this version range.

Commits viewable in compare view.

Updated Microsoft.NET.Test.Sdk from 18.10.1 to 18.11.0.

Release notes

Sourced from Microsoft.NET.Test.Sdk's releases.

18.11.0

What's Changed

New Contributors

Full Changelog: microsoft/vstest@v18.10.1...v18.11.0

Commits viewable in compare view.

Updated NUnit from 4.6.1 to 5.0.0.

Release notes

Sourced from NUnit's releases.

5.0.0

See release notes for details.

Commits viewable in compare view.

Updated NUnit3TestAdapter from 6.3.0 to 6.3.1.

Release notes

Sourced from NUnit3TestAdapter's releases.

6.3.1

This is a hotfix release for issue 1504

Commits viewable in compare view.

Updated Suave from 3.5.0 to 3.7.2.

Release notes

Sourced from Suave's releases.

3.7.2

  • Behaviour change:** a binding that cannot be bound (e.g. its port is already in use) is now reported to the caller. startWebServer throws the SocketException instead of returning normally, so a startWebServer cfg app; 0 program exits with a non-zero code and supervisors (systemd Restart=on-failure, Docker restart policies) see the failure. With startWebServerAsync, listening raises the exception instead of never completing (a program blocked on it hung for ever, even on SIGTERM) and the server task is faulted with it. With several bindings, one that fails stops the ones that did start, so startWebServer throws instead of carrying on with only some of them. Stopping the server by cancelling its token still completes cleanly. Adds AsyncResultCell.fail

3.7.1

  • Security: a client that opened a connection to an HTTPS binding and never completed the TLS handshake stopped that binding from accepting anyone else (with the default acceptorCount = 1, one idle TCP connection made the HTTPS site unreachable until it closed). The handshake now runs on the connection's own task instead of the accept loop, and is bounded by the new process-wide Tcp.tlsHandshakeTimeout (default 10 seconds; set it before starting the server). A connection whose handshake fails or times out now has its socket closed; previously the socket was left open
  • Proxy.proxy forwards requests faithfully: the target is built from rawPath and rawQuery (it used the decoded path and dropped the query, so /a/b%2Fc?x=1 arrived as /a/b/c), and a path on the upstream URI is kept as a prefix (proxy (Uri "http://backend/api") maps /users to /api/users). A request path with a . or .. segment (also percent-encoded) is answered with 400 instead of being able to leave that prefix
  • Proxy.proxy forwards every request header except hop-by-hop ones (RFC 9110 §7.6.1: Connection, Keep-Alive, Proxy-Connection, TE, Trailer, Transfer-Encoding, Upgrade, Proxy-Authorization, Proxy-Authenticate and any named in Connection), Host, Content-Length and Expect; it used to forward only User-Agent, Accept, Date, Content-Type and Content-Length, so Authorization, Cookie, API keys and the like were lost. The request body is forwarded whenever there is one (it was only forwarded for POST and PUT, so PATCH and DELETE lost theirs). multipart/form-data bodies are parsed by Suave before any WebPart runs and still cannot be forwarded
  • Proxy.proxy passes any upstream status through with its reason phrase; statuses Suave has no HttpCode for (e.g. 207, 418) used to become 502 while the upstream body was still sent. Response headers are forwarded without hop-by-hop headers and without Date/Server (Suave writes its own), and repeated headers such as Set-Cookie are kept as separate headers instead of being joined with commas
  • Behaviour change:** Proxy.proxy no longer trusts X-Forwarded-For, X-Forwarded-Proto, X-Forwarded-Host, Forwarded or X-Real-IP sent by the client: X-Forwarded-For is the connection's address, -Proto and -Host are the scheme and Host the proxy received, and Forwarded/X-Real-IP are dropped. A client could send X-Forwarded-Proto: https over plain HTTP, or any address in X-Forwarded-For, and have it passed on. Behind another reverse proxy, list its address in ProxyOptions.trustedProxies to keep its headers and extend its X-Forwarded-For chain
  • Security: the HttpClient shared by all proxies no longer keeps a cookie container. Upstream Set-Cookie responses were stored in it and sent with later proxied requests from every client
  • Add Proxy.proxyWith options upstream and Proxy.defaultProxyOptions (timeout, trustedProxies, dropRequestHeaders, onError). The proxy answers 504 when the upstream has not sent its response headers within the timeout (30 seconds by default; there was none) and 502 when it cannot be reached; onError is called with the exception first. proxy and proxyWith throw ArgumentException straight away for an upstream that is not an absolute http/https URI

3.7.0

  • Fix HTTP/2 responses whose content is a SocketTask being sent with status 200 and an empty body: Files.file, Files.browse, Stream.okStream, Stream.okStreamChunked, TransferEncoding.chunked, EventSource.handShake and custom writers now work over HTTP/2 (TLS with ALPN h2, h2c upgrade and h2c prior knowledge). Since HTTPS bindings advertise h2 first, browsers received empty static files and event streams from 3.6.1 and earlier. The HTTP/2 writer gives the task a per-stream connection: header lines the task writes join the HEADERS frame, HTTP/1.1 chunk framing is removed, and the body goes out as flow-controlled DATA frames as it is written; once the client resets the stream, writes return an error
  • HTTP/2 responses no longer carry connection-specific headers (Connection, Keep-Alive, Proxy-Connection, Transfer-Encoding, Upgrade, RFC 9113 §8.2.2); Transfer-Encoding: chunked made clients fail the stream with PROTOCOL_ERROR (curl exit 92)
  • New SuaveConfig.http2Enabled (default true, also withHttp2Enabled and HttpRuntime.http2Enabled): when false, HTTPS bindings offer only http/1.1 via ALPN, Upgrade: h2c is ignored and the HTTP/2 prior-knowledge preface is refused with 400. Code that builds SuaveConfig or HttpRuntime with a full record expression must add the field; { defaultConfig with ... } is unaffected
  • The h2c 101 Switching Protocols response, and any other 1xx response, no longer carries the default Content-Type: text/html
  • HTTP/2 response header blocks are HPACK-encoded under the connection's write lock, so concurrent streams cannot write their HEADERS frames in a different order from the encoder's dynamic table updates
  • Behaviour change:** defaultErrorHandler no longer returns the exception message and stack trace to "local" clients; every client gets a plain 500 Internal Server Error. The local check used the connection address, or an X-Forwarded-For/X-Real-IP header the client could set to 127.0.0.1; behind a reverse proxy on the same host (nginx -> 127.0.0.1) every remote client received stack traces. For development, opt in with the new developmentErrorHandler ({ defaultConfig with errorHandler = developmentErrorHandler }), which shows the HTML-encoded details to every client
  • HTTP/2 requests now carry the binding they arrived on in request.binding; it was the default http://0.0.0.0:8080, so request.binding.scheme.secure was false and request.url was wrong for HTTPS clients that negotiated HTTP/2 (a redirect-to-HTTPS check looped for them)
  • Docs: the deployment guide uses .NET 10 and the runtime image with a non-root user and a curl-free health check, shows graceful shutdown on SIGTERM, fixes the nginx WebSocket/keep-alive setup, uses X509CertificateLoader, and replaces the ASP.NET Core Module IIS example with HttpPlatformHandler; the HTTPS recipe's redirect keeps the query string and port
  • Validation.String validators (minLength, maxLength, exactLength, lengthBetween, matches, email, alphanumeric, alpha, numeric, contains, startsWith, endsWith) return Invalid with "Value is required" for a null input instead of throwing NullReferenceException, e.g. for a field System.Text.Json left null; notEmpty is unchanged
  • ValidationWebParts.validationErrorsToJson writes its output with Utf8JsonWriter, so fields and messages containing ", \ or control characters produce valid JSON; the shape is unchanged, the output is now compact (no spaces), and characters such as ', < and non-ASCII are written as \uXXXX escapes
  • Breaking: the <++> operator now preserves left-to-right order: a <++> b reports a's errors before b's and returns a's value when both pass (previously the reverse). a |> andAlso b is unchanged
  • HttpRequest.query returns (key, None) for a query key without a value (?flag), as documented, instead of (key, Some ""); ?key= is still (key, Some ""). queryFlag "flag" is now true for ?flag, and queryParam "flag" returns Choice2Of2 for it. Form parsing (form, formData) is unchanged
  • pathScan, pathScanCi and Sscanf.sscanf no longer wrap integers that are out of range for the target type: /items/99999999999 against pathScan "/items/%d" with an int handler now declines instead of passing 1215752191; the same applies to int16, uint16 and uint32 (and %x/%X/%o values that do not fit)
  • Behaviour change:** CORS.defaultCORSConfig no longer allows credentials (allowCookies = false). It used to reflect any Origin together with Access-Control-Allow-Credentials: true, which lets any web site make authenticated requests as your users. To allow credentials, list the trusted origins too: { defaultCORSConfig with allowedUris = InclusiveOption.Some [ "https://app.example.com" ]; allowCookies = true }
  • cors adds Vary: Origin (merged into an existing Vary) so caches do not serve one origin's CORS response to another
  • cors no longer sends Access-Control-Allow-Methods: GET, for a single allowed method; methods are joined as GET, POST
  • Add CORS.withCORS config handler, which answers preflight requests with 204 itself and runs handler only for actual requests, and CORS.corsPreflight config, which answers preflights and declines other requests (choose [ corsPreflight cfg; cors cfg >=> app ]). cors cfg >=> handler still lets the handler replace the preflight's 204, as documented
  • Behaviour change:** RateLimit.defaultKeyExtractor keys by the connection's remote address and ignores X-Forwarded-For/X-Real-IP, which a client could change on every request to avoid the limit. Behind a reverse proxy use the new RateLimit.trustedProxyKeyExtractor [ proxyAddress ], which reads X-Forwarded-For only on connections from the listed proxies. userKeyExtractor and headerKeyExtractor fall back to the new default
  • Each rateLimit WebPart keeps its own counters. All limiters used to share one store keyed only by the extracted key, so two limiters keyed by IP counted together, and limiters with different strategies denied every request after the first (e.g. a FixedWindow limiter returned 429 after a SlidingWindow one had seen the same IP). Idle entries are still cleaned up. getStats returns the first limiter that has an entry for the key
  • Add RateLimit.defaultRateLimitConfig; RateLimit.defaultConfig is obsolete because after open Suave.RateLimit it shadows the server's defaultConfig. The obsolete alias still shadows it until it is removed; use Web.defaultConfig meanwhile
  • securityHeaders replaces headers of the same name already on the response instead of adding a second copy (e.g. two Cache-Control headers)
  • Security header presets send X-XSS-Protection: 0 instead of 1; mode=block. strictConfig no longer sends the deprecated block-all-mixed-content or HSTS preload (opt in with withHSTS 31536000 true true), and sends Cache-Control: no-store instead of no-store, no-cache
  • Files.sendFile (and so file, browse, browseHome, browseFile) treats Range byte positions as inclusive: bytes=2-5 is now answered with Content-Range: bytes 2-5/10 and four bytes instead of three. Open-ended (bytes=5-) and suffix (bytes=-3) ranges are supported, a range past the end is clamped, a range starting at or after the end is answered with 416 and Content-Range: bytes */<length>, and malformed, multi-range or non-bytes headers get the whole file. Partial responses are never compressed
  • Files.sendFile no longer sends Content-Range on full 200 responses, compressed or not; it is only sent with 206 and 416
  • Upload temp files written for request.files are deleted once the response has been written (or the connection ends) instead of being left in the temp folder. Move or copy an upload during the request to keep it; streaming it back with Files.sendFile still works. Files written by a custom filePartSink are not touched
  • Files.browse, browseHome, browseFile, browseFileHome and dir decline a request whose path escapes the root (such as /../secret.txt) instead of throwing, so it gets the application's 404 rather than a 500. New Files.tryResolvePath; resolvePath still throws
  • When the compressed-files folder cannot be written to (the default, AppContext.BaseDirectory, is read-only under dotnet fsi and in read-only containers), compressible files are served uncompressed instead of the connection being closed without a response; the failure is reported once per folder through Globals.writeMessage
  • Docs: the file upload recipe and the file handling guide no longer build the destination path from the client-supplied file name, which allowed writing outside the upload folder with filename=../../x
  • The Suave.DotLiquid package declares DotLiquid >= 2.3.197; 3.6.1 and earlier declared DotLiquid with no lower bound (0.0), so NuGet picked DotLiquid 0.0.0 and the first render failed with MissingMethodException (Template.set_NamingConvention). Workaround for those versions: reference DotLiquid 2.3.197 explicitly. The DotLiquid docs now use | escape in their examples (DotLiquid does not HTML-escape output) and cover the response charset and template field naming
  • open Suave no longer shadows F#'s Result.Ok/Result.Error: the parser's ScanResult type (NeedMore | Found | Error) leaked its Error case into the Suave namespace, so bare Error "x" or | Error e -> in user code resolved to it. ScanResult is now internal and requires qualified access, and HttpReader.scanMarker and HttpReader.skip, which returned it, are now internal too. Code that matched on ScanResult or called those members must use HttpReader.readUntilPattern instead
  • Fix multipart/form-data bodies whose multipart/mixed part is followed by another part: the parser did not wait for the rest of the outer boundary line to be skipped, so when that data had not arrived yet the request hung or lost the parts after it
  • Security: EventSource.data and EventSource.send write one data: line per line of the data (split on CRLF, LF and CR), so line breaks in a message can no longer end the event and inject fields or extra events (e.g. Message.create "1" "hello\n\nevent: admin\ndata: x" produced a second admin event). esId, eventType, comment and the message id/type have CR and LF removed. send now writes the whole message in one write
  • Write failures are no longer swallowed, so streaming loops stop when the client disconnects (an EventSource.send loop used to keep running forever): Connection.asyncWriteBytes, Connection.writeChunk, EventSource.send/data/comment/dispatch/…, transferStream and transferStreamChunked raise the new Suave.Sockets.SocketWriteException (an IOException carrying the socket Error) when a write fails, which ends the response and closes the connection. New non-throwing variants return Task<Result<unit, Error>>: Connection.tryWriteBytes, Connection.tryFlush, Connection.tryWriteChunk, Connection.tryWriteLastChunk, EventSource.trySend and EventSource.tryComment. TcpTransport/SslTransport.write return Error instead of throwing when the socket is already shut down
  • Connection.writeChunk writes the raw bytes: it converted them to a UTF-8 string first, so non-UTF-8 data was corrupted and no longer matched the declared chunk length (FF FE 00 was declared as 3 bytes and sent as 7). New Connection.writeLastChunk / tryWriteLastChunk write the terminating 0\r\n\r\n chunk (as writeChunk [||] does)
  • TransferEncoding.chunked answers 200 when the response still has the initial 404 status of a fresh response (TransferEncoding.chunked writer alone used to answer 404); any other status set before it is kept, and a chunked 404 can be sent with TransferEncoding.chunked writer >=> Writers.setStatus HTTP_404. The response headers are now flushed before the writer runs, so writers can write straight to conn.transport
  • Breaking: EventSource.handShake keeps the headers already set on the response (it replaced them all) and no longer sends Access-Control-Allow-Origin: *. To allow cross-origin EventSource clients, compose it with Writers.setHeader "Access-Control-Allow-Origin" "*" (or your origin) or CORS.cors. Content-Type is always text/event-stream; charset=utf-8; Cache-Control: no-cache and X-Accel-Buffering: no are added unless already set
  • WebSocket frames are limited to SuaveConfig.webSocketMaxFrameSize bytes (new field, default 16 MiB; also on HttpRuntime). A frame announcing a larger payload is answered with a Close frame carrying code 1009 and the connection is dropped before any buffer is allocated or the readIntoByteSegment length function is called; previously a client could announce up to 2 GB per frame and read () allocated it up front. Override per socket with WebSocket.maxFrameSize. Code that builds SuaveConfig or HttpRuntime without { defaultConfig with ... } / { HttpRuntime.empty with ... } must set the new field
  • An exception thrown by a WebSocket handler (handShake, handShakeTask, handShakeWithSubprotocol) is reported through Globals.writeMessage and answered with a Close frame carrying code 1011 (new CloseCode.CLOSE_INTERNAL_ERROR); previously it escaped and Suave wrote an HTTP/1.1 500 response, with the exception text for local clients, onto the upgraded connection
  • handShake no longer writes an HTTP/1.1 404 Not Found response onto the connection when the WebSocket handler finishes, and a refused handshake now gets its 400 Bad Request / 405 Method Not Allowed instead of 404
  • Close frames sent by Suave carry a two-byte status code as RFC 6455 requires (they sent four bytes, so clients read status 0)
  • 101 Switching Protocols (and other 1xx) responses no longer get a default Content-Type: text/html header
  • WebSocket docs and recipes check the Origin header before handShake (cross-site WebSocket hijacking), answer Ping with Pong and Close with Close, and the broadcast recipe uses a MailboxProcessor hub that drops clients whose send fails

3.6.1

  • Keep-alive CPU per request is now within ≈1% of ASP.NET Core Minimal API on Linux with the server pinned to 4 cores (8.98 vs 8.89 µs, down from ≈9.7 µs in v3.6.0) (#​865)
  • Suave is compiled without F# .tail calls: async continuations in bind (>=>), choose, tryThen, inject, <|>, the router and others passed the HttpContext struct on as a tail call, which went through the runtime's slow, copying tail-call helper (#​865)
  • The request head is taken from the input with one pipe read and parsed in place, instead of three read/advance pairs; TcpTransport no longer takes a lock to fetch the socket on every read and write (#​865)
  • Benchmarks: benchmarks/cpu-per-request.sh measures server CPU time per request; benchmarks/HTTP_COMPARISON.md documents the pinned-core and perf profiling method (#​865)

3.6.0

  • Keep-alive performance: allocations per request fall from ≈5.7 KB to ≈1.24 KB for a routed empty response. In a same-host Linux comparison against ASP.NET Core Minimal API, Suave is now ahead at 256 connections and within ≈5% at 64 (#​862, #​864):
  • the connection's request loop waits for a complete request head, then parses the request line and headers synchronously; fragmented, oversized (beyond the 8 KiB line buffer), non-HTTP/1.x and body-carrying requests continue on the streaming parser
  • a request whose parsing, web part and response complete synchronously allocates no Task; processRequest and run keep their Task signatures
  • TCP and HTTPS reads and web part executions complete through reusable per-connection completion sources instead of a task { } wrapper and Async.StartImmediateAsTask per request; web part errors are recovered there with the same semantics as async.TryWith
  • reads no longer register on the server's cancellation token individually: each connection registers once and is shut down when the server stops, which also ends a pending read
  • no error message allocations for absent request headers, h2c checks only for Upgrade: h2c requests, allocation-free Content-Length formatting, status line and ASCII response headers written without task state or ToLowerInvariant, no URL decoding of paths without escapes, and a single exact-route lookup in Router
  • New HttpReader members (requestHeadReady, receive, commitReceived, tryReadRequestLineBuffered, tryReadHeadersBuffered) used by the request loop (#​862)
  • Request header names are matched with ordinal case-insensitive comparison; names with invalid Unicode no longer match through linguistic equivalence (#​862)
  • Add Globals.messageWriter to redirect or silence Suave's own console messages (startup banner, "Stopping TCP server", websocket disconnects); the test suite uses it to avoid a Console lock deadlock with Expecto that caused intermittent hangs (#​863)
  • Evict obsolete compressed artifacts: a recompressed resource's superseded copy is now deleted as part of the atomic cache swap, and the _temporary_compressed_files folder is swept - age- and count-bounded, see Compression.cleanupFolder - on server startup and shutdown (#​655)
  • Cached compressed copies that have gone missing from disk are treated as a cache miss instead of failing the request
  • Benchmarks: a Minimal API comparison server, balanced comparison and profiling scripts, and an exact per-request allocation probe; see benchmarks/HTTP_COMPARISON.md (#​862)

Commits viewable in compare view.

Updated System.Text.Json from 10.0.12 to 10.0.13.

Release notes

Sourced from System.Text.Json's releases.

No release notes found for this version range.

Commits viewable in compare view.

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore <dependency name> major version will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
  • @dependabot ignore <dependency name> minor version will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
  • @dependabot ignore <dependency name> will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
  • @dependabot unignore <dependency name> will remove all of the ignore conditions of the specified dependency
  • @dependabot unignore <dependency name> <ignore condition> will remove the ignore condition of the specified dependency and ignore conditions

Bumps fantomas from 8.0.4 to 8.1.0
Bumps fsharp-analyzers from 0.39.2 to 0.41.0
Bumps FSharp.Compiler.Service from 43.12.401 to 43.12.402
Bumps FSharp.Core from 10.1.401 to 10.1.402
Bumps FsUnit from 7.1.1 to 8.0.0
Bumps G-Research.FSharp.Analyzers from 0.25.0 to 0.26.0
Bumps Ionide.Analyzers from 0.19.0 to 0.20.0
Bumps Ionide.ProjInfo from 0.75.0 to 0.75.3
Bumps Microsoft.Extensions.Logging.Abstractions from 10.0.12 to 10.0.13
Bumps Microsoft.NET.Test.Sdk from 18.10.1 to 18.11.0
Bumps NUnit from 4.6.1 to 5.0.0
Bumps NUnit3TestAdapter from 6.3.0 to 6.3.1
Bumps Suave from 3.5.0 to 3.7.2
Bumps System.Text.Json from 10.0.12 to 10.0.13

---
updated-dependencies:
- dependency-name: fantomas
  dependency-version: 8.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget
- dependency-name: fsharp-analyzers
  dependency-version: 0.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget
- dependency-name: FSharp.Compiler.Service
  dependency-version: 43.12.402
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nuget
- dependency-name: FSharp.Core
  dependency-version: 10.1.402
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nuget
- dependency-name: FsUnit
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: nuget
- dependency-name: NUnit
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: nuget
- dependency-name: G-Research.FSharp.Analyzers
  dependency-version: 0.26.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget
- dependency-name: Ionide.Analyzers
  dependency-version: 0.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget
- dependency-name: Ionide.ProjInfo
  dependency-version: 0.75.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nuget
- dependency-name: Microsoft.Extensions.Logging.Abstractions
  dependency-version: 10.0.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nuget
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget
- dependency-name: NUnit3TestAdapter
  dependency-version: 6.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nuget
- dependency-name: Suave
  dependency-version: 3.7.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget
- dependency-name: System.Text.Json
  dependency-version: 10.0.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nuget
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added .NET Pull requests that update .net code dependencies Pull requests that update a dependency file labels Oct 22, 2026
@nojaf
nojaf merged commit 15ba2d3 into main Oct 22, 2026
11 checks passed
@nojaf
nojaf deleted the dependabot/nuget/dot-config/nuget-e3fe9c464e branch October 22, 2026 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file .NET Pull requests that update .net code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant