Repository navigation
[Bug] SetHttpHandler handler never runs in C#: SDK fails to deserialize the request object (msgpack ext 0x0b), client gets HTTP 200 with empty body #350
Replies: 4 comments
|
Same thing happens on the client, so it's not only A raw NUI callback gets invoked with In case anyone needs a workaround for now: only declare the parameters you actually read. The binder Client b106, |
|
Hello, I just updated your post to remove references to |
|
Hi, thanks this will be fixed in the next patch. |
|
Hello, |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Summary
In a C# (.NET 10) server resource, a handler registered through
SetHttpHandleris never actually invoked: the SDK fails to deserialize the request object the server hands to the function reference, because the request map contains callback references serialized as MessagePack extension type0x0b, whichPrimitiveObjectFormatterdoes not support. The exception is only visible in the server console; the HTTP client still receives HTTP 200 with an empty body, so from the outside the request looks like it succeeded. This makes inbound HTTP (webhooks, long-polling, REST-style endpoints) unusable from C# resources. An equivalent Lua resource on the same server build serves the same route correctly.Issue type
Server
Repro rate
Always
Server build version
b106 (
versioncommand andinfo.jsonboth reportFXServer-early-access b106 win32; there is no numeric build id on this early-access artifact). Also reproduced on b105. SDK:CitizenFX.FiveM.Server/CitizenFX.FiveM.Shared0.0.3-alpha.Server details
Platform
Windows
OS version / distribution
Windows 11 Pro 25H2 (build 26200)
CPU
AMD Ryzen 9 9950X (16c/32t)
RAM
128 GB DDR5-4800
Using txAdmin?
No
Hosting provider
Self-hosted
Machine type
Dedicated
DDoS protection
No
Reproduction
Steps to Reproduce
CitizenFX.FiveM.Server/CitizenFX.FiveM.Shared0.0.3-alpha (output asHttpProbe.Server.net.dll):fxmanifest.lua:
ensurethe resource; the console logs[HTTPH] SetHttpHandler OK.curl -i http://127.0.0.1:<port>/<resource-name>/pingThe same failure occurs with a typed signature
Action<Dictionary<string, object>, Dictionary<string, object>>— only the target type name in the exception changes.Expected Behavior
The handler runs and receives a usable request object (headers, method, address, path, plus callable
setDataHandler/setCancelHandlerreferences), analogous to what Lua and JS handlers receive from the sameSetHttpHandlernative. Failing that, the HTTP client should at least receive an error status — not a 200.Actual Behavior
Failed to invoke function reference ...: InvalidWrappedCallArgExceptionin the server console (full trace below).SetHttpHandleron the same server build serves the same route normally (200 with the expected body), so the server side of the pipeline appears fine — the failure is in the C# SDK's argument deserialization.Evidence
Server console output on b106 (identical on every request;
Action<object, object>variant):Note the
"setDataHandler":[11,"NQ=="]/"setCancelHandler":[11,"NA=="]entries in the logged request map — these are the msgpack extension (type0x0b) callback references thatPrimitiveObjectFormatterrejects. The request shape matchescitizen-server-impl/src/ResourceHttpHandler.cpp(map ofheaders, method, address, path, setDataHandler, setCancelHandler, where the two handlers and the response'swrite/writeHead/sendare callback refs).Client side for the same request:
HTTP/1.1 200 OKwithContent-Length: 0.Additional Context
Action<Dictionary<string, MessagePackBuffer>, Dictionary<string, FunctionReference>>deserializes successfully, and callingres["writeHead"]/res["send"]produces a correct HTTP response (verified on the same builds, including reading the POST body viasetDataHandler). SoFunctionReferenceFormatterhandles the callback-ref extension types fine; the failure is specific to the untyped path wherePrimitiveObjectFormatterencounters ext code0x0binsideobject/Dictionary<string, object>values. Teaching the SDK's primitive-object path to materialize callback-ref extensions as callable references (like Lua/JS do) would fix the general case.ResourceHttpHandlerstill completes the response after the script-side failure, the caller sees 200/empty rather than a 5xx, which makes this hard to detect from monitoring.Native.SetHttpHandlertakes a raw funcref id,FunctionReference's constructor is internal, and registering viaFuncRefManageremitswarning FIVEM001(internal-use API). A supported wrapper would make this path testable end to end.SetHttpHandler OKbefore the first request arrives.All reactions