{"record":{"id":"c4a186e3e8b03e79","repo":"Anuken/Mindustry","slug":"player-cannot-respawn","errorCode":null,"errorMessage":"Player cannot respawn.","messagePattern":"Player cannot respawn\\.","errorType":"validation","errorClass":"ValidateException","httpStatus":null,"severity":"warning","filePath":"core/src/mindustry/input/InputHandler.java","lineNumber":826,"sourceCode":"            Time.run(Fx.unitSpirit.lifetime, () -> Fx.unitControl.at(unit.x, unit.y, 0f, unit));\n            if(!player.dead()){\n                Fx.unitSpirit.at(player.x, player.y, 0f, unit);\n            }\n        }else if(net.server()){\n            //reject forwarding the packet if the unit was dead, AI or team\n            throw new ValidateException(player, \"Player attempted to control invalid unit.\");\n        }\n\n        Events.fire(new UnitControlEvent(player, unit));\n    }\n\n    @Remote(targets = Loc.both, called = Loc.server, forward = true)\n    public static void unitClear(Player player){\n        if(player == null) return;\n\n        //make sure player is allowed to control the building\n        if(net.server() && !netServer.admins.allowAction(player, ActionType.respawn, action -> {})){\n            throw new ValidateException(player, \"Player cannot respawn.\");\n        }\n\n        if(!player.dead() && !player.unit().spawnedByCore){\n            var docked = player.unit().dockedType;\n\n            //get best core unit type as approximation\n            if(docked == null){\n                var closest = player.bestCore();\n                if(closest != null){\n                    docked = ((CoreBlock)closest.block).unitType;\n                }\n            }\n\n            //respawn if necessary\n            if(docked != null && docked.coreUnitDock){\n                //TODO animation, etc\n                Fx.spawn.at(player);\n","sourceCodeStart":808,"sourceCodeEnd":844,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/core/src/mindustry/input/InputHandler.java#L808-L844","documentation":"Thrown server-side as ValidateException in unitClear when netServer.admins.allowAction(respawn) returns false. Guards the respawn/leave-unit action behind the admin permission layer; a denied respawn aborts the packet.","triggerScenarios":"Client sends unitClear (request to leave current unit / respawn at core) and the admin layer denies the respawn action. Server-side throw in the @Remote handler.","commonSituations":"Permission plugin restricts respawning; server config disables free respawn; a client spams respawn while a cooldown/permission blocks it.","solutions":["Server: handle ValidateException as an expected denial rather than propagating.","Review netServer.admins rules / permission plugin config if legitimate respawns are blocked.","Clients can pre-check permissions if the server exposes them, otherwise expect possible denial."],"exampleFix":"// before\nCall.unitClear(player);\n\n// after (server-side handler)\ntry{\n    // remote invocation path\n}catch(ValidateException e){\n    Log.debug(\"@ denied respawn: @\", e.player, e.getMessage());\n}","handlingStrategy":"try-catch","validationCode":"// no generic client pre-check for permissions; clients may pre-check rules if exposed\nif(/* server-exposed permission check */ false){ return; }","typeGuard":null,"tryCatchPattern":"try{ Call.unitClear(player); }catch(mindustry.net.ValidateException e){ Log.debug(\"rejected respawn from @\", e.player); }","preventionTips":["Servers: handle ValidateException on respawn as expected.","Document respawn permission rules for players.","Avoid spamming respawn requests; rate-limit on the client.","Review permission plugin config if valid respawns are denied."],"tags":["network","validation","multiplayer","server","respawn"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}