Anuken/Mindustry · error · IOException

Invalid Steam ID: {}

Error message

Invalid Steam ID: {}

What it means

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.

Source

Thrown at desktop/src/mindustry/desktop/steam/SNet.java:171

        if(con != null){
            con.pollWrites();
        }

        return readAny;
    }

    @Override
    public void connectClient(String ip, int port, Runnable success) throws IOException{

        if(ip.startsWith("steam:")){
            String lobbyname = ip.substring("steam:".length());
            try{
                SteamID lobby = SteamID.createFromNativeHandle(Long.parseLong(lobbyname));
                joinCallback = success;
                smat.joinLobby(lobby);
            }catch(NumberFormatException e){
                throw new IOException("Invalid Steam ID: " + lobbyname);
            }
        }else if (ip.startsWith("steamserver:")){
            String server = ip.substring("steamserver:".length());
            try{
                SteamID serverID = SteamID.createFromNativeHandle(Long.parseLong(server));
                if(!serverID.isValid()) throw new IOException("Invalid Steam ID structure: " + server);

                Core.app.post(() -> {
                    currentLobby = null;
                    currentServer = serverID;
                    joinCallback = success;

                    //begin the handshake; success/handleClientReceived/setClientConnected fire once onConnectionStatusChanged reports Connected
                    clientConnection = snet.connectP2P(serverID, 0);

                    Core.app.post(() -> {  // TODO: This gets hidden and I can't figure out how to not do so.
                        ui.loadfrag.show("@connecting");
                        ui.loadfrag.setButton(() -> {

View on GitHub (pinned to f695ad7e60)

Solutions

  1. Sanitize the substring after 'steam:' before calling connectClient: trim whitespace and strip any non-digit characters.
  2. Validate with a regex like ^\d+$ and reject early with a user-facing message if it fails.
  3. If the input came from a 'steam://' URL, strip the full URL scheme first, not just the 'steam:' prefix.
  4. Log the raw input length alongside the failure so truncated handles are easy to diagnose.

Example fix

// before
String lobbyname = ip.substring("steam:".length());
SteamID lobby = SteamID.createFromNativeHandle(Long.parseLong(lobbyname));

// after
String lobbyname = ip.substring("steam:".length()).trim();
if(!lobbyname.matches("\\d+")) throw new IOException("Invalid Steam ID (not numeric): " + lobbyname);
SteamID lobby = SteamID.createFromNativeHandle(Long.parseLong(lobbyname));
Defensive patterns

Strategy: validation

Validate before calling

// Run before connectClient when ip starts with "steam:"
String handle = ip.substring("steam:".length()).trim();
if(handle.isEmpty() || !handle.matches("\\d+")){
    throw new IllegalArgumentException("Steam lobby handle must be numeric: '" + handle + "'");
}
long parsed = Long.parseLong(handle);

Type guard

// Narrow a connect string to a confirmed-numeric lobby handle.
static OptionalLong parseSteamLobbyHandle(String ip){
    if(ip == null || !ip.startsWith("steam:")) return OptionalLong.empty();
    String h = ip.substring("steam:".length()).trim();
    return h.matches("\\d+") ? OptionalLong.of(Long.parseLong(h)) : OptionalLong.empty();
}

Try / catch

try{
    net.connectClient(ip, port, success);
}catch(IOException e){
    if(e.getMessage() != null && e.getMessage().startsWith("Invalid Steam ID")){
        ui.showErrorMessage("@invalidsteam.lobby");
    }else throw e;
}

Prevention

When it happens

Trigger: 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').

Common situations: 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.

Related errors


AI-assisted analysis of Anuken/Mindustry@f695ad7e60 (2026-08-14). Data as JSON: /api/errors/aaac1859fd54d4ed. Report an issue: GitHub.