{"record":{"id":"01bad5a7e4c99a10","repo":"dianping/cat","slug":"unknown-identifier-int-name","errorCode":null,"errorMessage":"Unknown identifier int name","messagePattern":"Unknown identifier int name","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"cat-core/src/main/java/com/dianping/cat/message/codec/PlainTextMessageCodec.java","lineNumber":268,"sourceCode":"\n\t\t\ttree.findOrCreateHeartbeats().add(heartbeat);\n\n\t\t\tString heartbeatStatus = helper.read(ctx, TAB);\n\t\t\tString heartbeatData = helper.read(ctx, TAB);\n\n\t\t\thelper.read(ctx, LF); // get rid of line feed\n\t\t\theartbeat.setTimestamp(m_dateHelper.parse(timestamp));\n\t\t\theartbeat.setStatus(heartbeatStatus);\n\t\t\theartbeat.addData(heartbeatData);\n\n\t\t\tif (parent != null) {\n\t\t\t\tparent.addChild(heartbeat);\n\t\t\t\treturn parent;\n\t\t\t} else {\n\t\t\t\treturn heartbeat;\n\t\t\t}\n\t\tdefault:\n\t\t\tthrow new RuntimeException(\"Unknown identifier int name\");\n\t\t}\n\t}\n\n\tprotected void decodeMessage(Context ctx, MessageTree tree) {\n\t\tStack<DefaultTransaction> stack = new Stack<DefaultTransaction>();\n\t\tMessage parent = decodeLine(ctx, null, stack, tree);\n\n\t\ttree.setMessage(parent);\n\n\t\twhile (ctx.getBuffer().readableBytes() > 0) {\n\t\t\tMessage message = decodeLine(ctx, (DefaultTransaction) parent, stack, tree);\n\n\t\t\tif (message instanceof DefaultTransaction) {\n\t\t\t\tparent = message;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/dianping/cat/blob/e815e74d4c2dd74edac831241f1253fcc7d25381/cat-core/src/main/java/com/dianping/cat/message/codec/PlainTextMessageCodec.java#L250-L286","documentation":"PlainTextMessageCodec.decodeLine switches on a single-byte identifier at the start of each line ('t','T','E','M','H','L'...). The default branch throws RuntimeException(\"Unknown identifier int name\") — the message text is garbled ('int name' for 'identifier') and omits the byte value, but the cause is always a line that starts with an unexpected character.","triggerScenarios":"Decoding a PT1 payload where a line's leading byte is not a known identifier: line desynchronization (a field containing an embedded newline), truncation, or version drift adding a new line type this codec does not support.","commonSituations":"Event/transaction data strings containing raw newline characters that break the line-oriented format; mixed client/server versions introducing new record types; hand-crafted test payloads with wrong tags.","solutions":["Enable a hex/UTF-8 dump of the buffer at the failure point to see which character was read (the exception does not include it).","Strip or escape CR/LF in message data strings on the producer side so lines stay intact.","Align client and server versions so both understand the same identifier set.","If constructing payloads manually, start each line with a valid identifier byte ('t','T','E','M','H','L')."],"exampleFix":"// before: raw newline inside data breaks next line's identifier\nString data = \"a\\nb\"; // next line begins 'b' -> Unknown identifier\n\n// after: sanitize\nString data = raw.replace('\\n', ' ').replace('\\r', ' ');","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (RuntimeException e) { if (\"Unknown identifier int name\".equals(e.getMessage())) { abort decoding this payload; log buffer hexdump; } else throw e; }","preventionTips":["Sanitize CR/LF out of all message data fields before they enter the wire format.","Keep identifier byte vocabulary in sync across versions.","Log the failing byte offset — the exception omits the offending character."],"tags":["protocol","text-decoding","line-framing","sanitization"],"backgroundTag":null,"analyzedSha":"e815e74d4c2dd74edac831241f1253fcc7d25381","analyzedAt":"2026-08-14T14:22:34.512Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}