{"record":{"id":"2ed1c2539ae7a910","repo":"dianping/cat","slug":"invalid-message-id-format-s","errorCode":null,"errorMessage":"Invalid message ID format: %s","messagePattern":"Invalid message ID format: (.+?)","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"cat-core/src/main/java/com/dianping/cat/message/tree/MessageId.java","lineNumber":73,"sourceCode":"\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\thour = Integer.parseInt(messageId.substring(i + 1, end));\n\t\t\t\t\tend = i;\n\t\t\t\t\tpart--;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tipAddressInHex = messageId.substring(i + 1, end);\n\t\t\t\t\tdomain = messageId.substring(0, i);\n\t\t\t\t\tpart--;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (domain == null || ipAddressInHex == null || hour < 0 || index < 0) {\n\t\t\tthrow new RuntimeException(\"Invalid message ID format: \" + messageId);\n\t\t} else {\n\t\t\treturn new MessageId(domain, ipAddressInHex, hour, index);\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean equals(Object obj) {\n\t\tif (obj instanceof MessageId) {\n\t\t\tMessageId o = (MessageId) obj;\n\n\t\t\tif (!m_domain.equals(o.m_domain)) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (!m_ipAddressInHex.equals(o.m_ipAddressInHex)) {\n\t\t\t\treturn false;\n\t\t\t}\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/dianping/cat/blob/e815e74d4c2dd74edac831241f1253fcc7d25381/cat-core/src/main/java/com/dianping/cat/message/tree/MessageId.java#L55-L91","documentation":"MessageId.parse throws this RuntimeException when the input string cannot be split into the required four dash-separated parts: domain-ipAddressInHex-hour-index. The parser scans right-to-left expecting exactly three '-' delimiters; if domain or ip stays null, or hour/index remain -1 (including the case where Integer.parseInt fails and throws first), the format is declared invalid. CAT message IDs are conventionally produced as domain-hexip-hour-index (e.g. \"mydomain-c0a86401-3600-1\"), so any ID not built by MessageId.toString()/CAT itself will fail.","triggerScenarios":"Calling MessageId.parse(messageId) with a string that has fewer than three '-' characters, non-numeric hour or index segments (Integer.parseInt throws NumberFormatException first), negative hour/index values, or null/empty strings. Common when parsing IDs received over HTTP headers, from log files, or cross-language SDKs (e.g. go/php) that format the ID differently.","commonSituations":"Consuming CAT message-tree IDs produced by non-Java SDKs with different separators; truncated IDs copied from logs or HTTP headers; passing a CAT domain name or path instead of the full message ID; trailing whitespace/newline in the ID string read from a file.","solutions":["Ensure the ID has exactly the shape <domain>-<hexIp>-<hour>-<index>, e.g. by generating it with MessageId.toString() or the CAT client itself","Sanitize input before parsing: trim whitespace and strip surrounding quotes/newlines","Validate the shape with a regex such as ^[^-]+-[0-9a-fA-F]+-\\d+-\\d+$ before calling parse","If integrating cross-language SDKs, normalize their ID format to the Java convention before handing it to MessageId.parse"],"exampleFix":"// before\nMessageId id = MessageId.parse(rawIdFromHttpHeader);\n\n// after\nString raw = rawIdFromHttpHeader == null ? \"\" : rawIdFromHttpHeader.trim();\nif (!raw.matches(\"^[^-]+-[0-9a-fA-F]+-\\\\d+-\\\\d+$\")) {\n    throw new IllegalArgumentException(\"Bad message id: \" + raw);\n}\nMessageId id = MessageId.parse(raw);","handlingStrategy":"validation","validationCode":"private static final Pattern MESSAGE_ID = Pattern.compile(\"^[^-]+-[0-9a-fA-F]+-\\\\d+-\\\\d+$\");\n\npublic static boolean isValidMessageId(String id) {\n    return id != null && MESSAGE_ID.matcher(id).matches();\n}\n\n// use before parse\nif (isValidMessageId(raw)) {\n    MessageId parsed = MessageId.parse(raw);\n}","typeGuard":"public static boolean isValidMessageId(String id) {\n    if (id == null) return false;\n    String[] parts = id.split(\"-\");\n    if (parts.length != 4) return false;\n    try {\n        return Integer.parseInt(parts[2]) >= 0 && Integer.parseInt(parts[3]) >= 0;\n    } catch (NumberFormatException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    MessageId id = MessageId.parse(raw);\n} catch (RuntimeException e) {\n    if (e instanceof NumberFormatException || e.getMessage().startsWith(\"Invalid message ID format\")) {\n        // tolerate bad external IDs: skip or generate a fresh one\n        logger.warn(\"Unparseable message id: \" + raw);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always generate IDs via MessageId.toString() or the CAT client instead of hand-formatting strings","Treat message IDs from external sources (HTTP headers, logs, other SDKs) as untrusted input","Trim and length-check incoming IDs before parsing; expect NumberFormatException for non-numeric hour/index"],"tags":["cat","java","message-id","parsing","validation"],"backgroundTag":null,"analyzedSha":"e815e74d4c2dd74edac831241f1253fcc7d25381","analyzedAt":"2026-08-14T14:22:34.512Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}