{"record":{"id":"b67f0182a865a98e","repo":"OpenRA/OpenRA","slug":"received-packet-from-disconnected-client-clienti","errorCode":null,"errorMessage":"Received packet from disconnected client '{clientId}'","messagePattern":"Received packet from disconnected client '(.+?)'","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"critical","filePath":"OpenRA.Game/Network/OrderManager.cs","lineNumber":194,"sourceCode":"\n\t\tpublic void ReceiveImmediateOrders(int clientId, OrderPacket orders)\n\t\t{\n\t\t\tforeach (var o in orders.GetOrders(World))\n\t\t\t{\n\t\t\t\tUnitOrders.ProcessOrder(this, World, clientId, o);\n\n\t\t\t\t// A mod switch or other event has pulled the ground from beneath us\n\t\t\t\tif (disposed)\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tpublic void ReceiveOrders(int clientId, (int Frame, OrderPacket Orders) orders)\n\t\t{\n\t\t\tif (pendingOrders.TryGetValue(clientId, out var queue))\n\t\t\t\tqueue.Enqueue((orders.Frame, orders.Orders));\n\t\t\telse\n\t\t\t\tthrow new InvalidDataException($\"Received packet from disconnected client '{clientId}'\");\n\t\t}\n\n\t\tvoid ReceiveAllOrdersAndCheckSync()\n\t\t{\n\t\t\tConnection.Receive(this);\n\t\t}\n\n\t\tbool IsReadyForNextFrame => GameStarted && pendingOrders.All(p => p.Value.Count > 0);\n\n\t\tpublic int SuggestedTimestep\n\t\t{\n\t\t\tget\n\t\t\t{\n\t\t\t\tif (World == null)\n\t\t\t\t\treturn Ui.Timestep;\n\n\t\t\t\tif (World.IsLoadingGameSave)\n\t\t\t\t\treturn 1;","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/OpenRA/OpenRA/blob/a520984d91eda9de48a62b1d15c1e3bad0d4fb1a/OpenRA.Game/Network/OrderManager.cs#L176-L212","documentation":"Thrown by OrderManager.ReceiveOrders when an order packet arrives from a clientId that has no entry in the pendingOrders dictionary. Each connected client is registered in pendingOrders; a packet from an unknown id means the client was never registered (or was already removed as disconnected), so the packet cannot be queued and is treated as a protocol error.","triggerScenarios":"ReceiveOrders(clientId, orders) is called where pendingOrders does not contain clientId — e.g. the client disconnected and was removed from pendingOrders, but a stray/late packet still arrives; or a server relayed a packet for an id the local client never saw register.","commonSituations":"A client disconnects and a final in-flight packet is processed after removal; network/server logic forwarding packets for a clientId outside the expected range; a reconnect or mod-switch state transition leaving pendingOrders inconsistent with the connection.","solutions":["If you maintain custom networking, ensure packets for a clientId are only dispatched while that client is registered in pendingOrders (guard with a ContainsKey check before calling ReceiveOrders).","For end users, this usually indicates a transient desync/disconnect; restarting the match typically resolves it.","If persistent across all games, verify all peers run the same engine version."],"exampleFix":"// caller guard before dispatching a packet to OrderManager\n// before\norderManager.ReceiveOrders(o.ClientId, orders);\n// after\nif (pendingClientIds.Contains(o.ClientId))\n    orderManager.ReceiveOrders(o.ClientId, orders);","handlingStrategy":"validation","validationCode":"// Guard dispatch: only forward packets for registered clients\nif (orderManager.PendingClientIds.Contains(o.ClientId))\n    orderManager.ReceiveOrders(o.ClientId, orders);\nelse\n    Log.Write(\"network\", $\"Dropping packet for unregistered client {o.ClientId}\");","typeGuard":null,"tryCatchPattern":"try { orderManager.ReceiveOrders(clientId, orders); }\ncatch (InvalidDataException ex) when (ex.Message.Contains(\"disconnected client\"))\n{ /* tolerate stray late packets from a just-disconnected client */ }","preventionTips":["Register every client in pendingOrders before dispatching its first packet.","Drop, don't throw, for packets arriving shortly after a known disconnect (grace period).","Keep custom networking code's client-lifecycle state in sync with the OrderManager."],"tags":["network","multiplayer","orders","desync"],"backgroundTag":null,"analyzedSha":"a520984d91eda9de48a62b1d15c1e3bad0d4fb1a","analyzedAt":"2026-08-13T15:30:14.787Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}