{"record":{"id":"aaac1859fd54d4ed","repo":"Anuken/Mindustry","slug":"invalid-steam-id","errorCode":null,"errorMessage":"Invalid Steam ID: {}","messagePattern":"Invalid Steam ID: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"desktop/src/mindustry/desktop/steam/SNet.java","lineNumber":171,"sourceCode":"\n        if(con != null){\n            con.pollWrites();\n        }\n\n        return readAny;\n    }\n\n    @Override\n    public void connectClient(String ip, int port, Runnable success) throws IOException{\n\n        if(ip.startsWith(\"steam:\")){\n            String lobbyname = ip.substring(\"steam:\".length());\n            try{\n                SteamID lobby = SteamID.createFromNativeHandle(Long.parseLong(lobbyname));\n                joinCallback = success;\n                smat.joinLobby(lobby);\n            }catch(NumberFormatException e){\n                throw new IOException(\"Invalid Steam ID: \" + lobbyname);\n            }\n        }else if (ip.startsWith(\"steamserver:\")){\n            String server = ip.substring(\"steamserver:\".length());\n            try{\n                SteamID serverID = SteamID.createFromNativeHandle(Long.parseLong(server));\n                if(!serverID.isValid()) throw new IOException(\"Invalid Steam ID structure: \" + server);\n\n                Core.app.post(() -> {\n                    currentLobby = null;\n                    currentServer = serverID;\n                    joinCallback = success;\n\n                    //begin the handshake; success/handleClientReceived/setClientConnected fire once onConnectionStatusChanged reports Connected\n                    clientConnection = snet.connectP2P(serverID, 0);\n\n                    Core.app.post(() -> {  // TODO: This gets hidden and I can't figure out how to not do so.\n                        ui.loadfrag.show(\"@connecting\");\n                        ui.loadfrag.setButton(() -> {","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/desktop/src/mindustry/desktop/steam/SNet.java#L153-L189","documentation":"Thrown by connectClient when joining a Steam lobby whose handle string is not a base-10 integer. The code parses the substring after the 'steam:' prefix with Long.parseLong; any non-numeric value raises NumberFormatException, which is caught and rethrown as this IOException. Steam lobbies are addressed by a numeric native handle, so the input must be digits only.","triggerScenarios":"Calling connectClient(\"steam:<value>\", ...) where <value> is empty, contains non-digit characters, or carries a trailing/leading wrapper (e.g. 'steam:abc', 'steam:', 'steam:123 456').","commonSituations":"A user pastes a lobby link that includes URL scaffolding or whitespace; a clipboard contains a steam:// URL wrapper around the handle; the lobby handle is truncated during copy-paste; an automated launcher feeds an untrimmed config value.","solutions":["Sanitize the substring after 'steam:' before calling connectClient: trim whitespace and strip any non-digit characters.","Validate with a regex like ^\\d+$ and reject early with a user-facing message if it fails.","If the input came from a 'steam://' URL, strip the full URL scheme first, not just the 'steam:' prefix.","Log the raw input length alongside the failure so truncated handles are easy to diagnose."],"exampleFix":"// before\nString lobbyname = ip.substring(\"steam:\".length());\nSteamID lobby = SteamID.createFromNativeHandle(Long.parseLong(lobbyname));\n\n// after\nString lobbyname = ip.substring(\"steam:\".length()).trim();\nif(!lobbyname.matches(\"\\\\d+\")) throw new IOException(\"Invalid Steam ID (not numeric): \" + lobbyname);\nSteamID lobby = SteamID.createFromNativeHandle(Long.parseLong(lobbyname));","handlingStrategy":"validation","validationCode":"// Run before connectClient when ip starts with \"steam:\"\nString handle = ip.substring(\"steam:\".length()).trim();\nif(handle.isEmpty() || !handle.matches(\"\\\\d+\")){\n    throw new IllegalArgumentException(\"Steam lobby handle must be numeric: '\" + handle + \"'\");\n}\nlong parsed = Long.parseLong(handle);","typeGuard":"// Narrow a connect string to a confirmed-numeric lobby handle.\nstatic OptionalLong parseSteamLobbyHandle(String ip){\n    if(ip == null || !ip.startsWith(\"steam:\")) return OptionalLong.empty();\n    String h = ip.substring(\"steam:\".length()).trim();\n    return h.matches(\"\\\\d+\") ? OptionalLong.of(Long.parseLong(h)) : OptionalLong.empty();\n}","tryCatchPattern":"try{\n    net.connectClient(ip, port, success);\n}catch(IOException e){\n    if(e.getMessage() != null && e.getMessage().startsWith(\"Invalid Steam ID\")){\n        ui.showErrorMessage(\"@invalidsteam.lobby\");\n    }else throw e;\n}","preventionTips":["Normalize every connect string at the UI boundary: trim whitespace and strip enclosing URL schemes.","Reject non-digit lobby handles before they reach connectClient with a user-facing message.","Distinguish the 'steam:' (lobby) and 'steamserver:' (direct) prefixes at input time so they cannot be confused."],"tags":["networking","steam","validation","client"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}