{"record":{"id":"5d223429dffc2dbd","repo":"pinpoint-apm/pinpoint","slug":"agentstarttimeindex-not-found-transactionid","errorCode":null,"errorMessage":"agentStartTimeIndex not found:${transactionId}","messagePattern":"agentStartTimeIndex not found:(.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"commons-profiler/src/main/java/com/navercorp/pinpoint/common/profiler/util/TransactionIdUtils.java","lineNumber":98,"sourceCode":"        BytesUtils.writeVar64(transactionSequence, buffer, offset);\n        return buffer;\n    }\n\n    public static TransactionId parseTransactionId(final String transactionId) {\n        Objects.requireNonNull(transactionId, \"transactionId\");\n\n        final int agentIdIndex = nextIndex(transactionId, 0);\n        if (agentIdIndex == -1) {\n            throw new IllegalArgumentException(\"agentIndex not found:\" + transactionId);\n        }\n        if (!IdValidateUtils.checkId(transactionId, 0, agentIdIndex)) {\n            throw new IllegalArgumentException(\"invalid transactionId:\" + transactionId);\n        }\n        final String agentId = transactionId.substring(0, agentIdIndex);\n\n        final int agentStartTimeIndex = nextIndex(transactionId, agentIdIndex + 1);\n        if (agentStartTimeIndex == -1) {\n            throw new IllegalArgumentException(\"agentStartTimeIndex not found:\" + transactionId);\n        }\n        final long agentStartTime = parseLong(transactionId, agentIdIndex + 1, agentStartTimeIndex);\n\n        int transactionSequenceIndex = nextIndex(transactionId, agentStartTimeIndex + 1);\n        if (transactionSequenceIndex == -1) {\n            // next index may not exist since default value does not have a delimiter after transactionSequence.\n            // may need fixing when id spec changes\n            transactionSequenceIndex = transactionId.length();\n        }\n        final long transactionSequence = parseLong(transactionId, agentStartTimeIndex + 1, transactionSequenceIndex);\n        return TransactionId.of(agentId, agentStartTime, transactionSequence);\n    }\n\n    private static int nextIndex(String transactionId, int fromIndex) {\n        return transactionId.indexOf(TRANSACTION_ID_DELIMITER_CHAR, fromIndex);\n    }\n\n    private static long parseLong(String transactionId, int beginIndex, int endIndex) {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/commons-profiler/src/main/java/com/navercorp/pinpoint/common/profiler/util/TransactionIdUtils.java#L80-L116","documentation":"TransactionIdUtils.parseTransactionId splits a transactionId string (format: agentId^agentStartTime^transactionSequence) on delimiters. When no second delimiter exists after the agentId, nextIndex returns -1 and this IllegalArgumentException is thrown, meaning the transactionId string is malformed and cannot be decomposed into its components.","triggerScenarios":"Calling TransactionIdUtils.parseTransactionId with a string that has an agentId but no delimiter after it, e.g. 'myAgentId' or 'myAgentId12345' (missing the separator between agentId and agentStartTime).","commonSituations":"Passing a raw string value (agentId alone, or a traceId copied partially) instead of a full transactionId; hand-building transactionId strings with the wrong delimiter; older/newer pinpoint versions or custom storage rows where the id was truncated or not encoded with TransactionIdUtils.formatString.","solutions":["Verify the transactionId is produced by TransactionIdUtils.formatString / TransactionId objects, not hand-concatenated","Check that the string contains the expected delimiters between agentId, agentStartTime, and transactionSequence before calling parseTransactionId","Validate the id came from a pinpoint span/trace source and was not truncated by storage or logging","Wrap parseTransactionId in try-catch and treat the input as a malformed/foreign id"],"exampleFix":"// before\nTransactionId id = TransactionIdUtils.parseTransactionId(agentIdLine);\n// after\nif (agentIdLine != null && agentIdLine.indexOf(TransactionIdUtils.AGENT_ID_DELIMITER) > -1) {\n    TransactionId id = TransactionIdUtils.parseTransactionId(agentIdLine);\n} else {\n    throw new IllegalArgumentException(\"malformed transactionId: \" + agentIdLine);\n}","handlingStrategy":"validation","validationCode":"boolean isParseableTransactionId(String s) {\n    if (s == null) return false;\n    int first = s.indexOf(TransactionIdUtils.AGENT_ID_DELIMITER);\n    return first > 0 && s.indexOf(TransactionIdUtils.AGENT_ID_DELIMITER, first + 1) != -1;\n}","typeGuard":"boolean isParseableTransactionId(String s) {\n    if (s == null) return false;\n    int first = s.indexOf(TransactionIdUtils.AGENT_ID_DELIMITER);\n    return first > 0 && s.indexOf(TransactionIdUtils.AGENT_ID_DELIMITER, first + 1) != -1;\n}","tryCatchPattern":"try {\n    TransactionId id = TransactionIdUtils.parseTransactionId(txId);\n} catch (IllegalArgumentException e) {\n    log.warn(\"malformed transactionId: {}\", txId, e);\n    // treat as foreign/legacy id, skip or fall back\n}","preventionTips":["Only pass transactionIds produced by TransactionIdUtils.formatString or TransactionId objects","Never hand-concatenate transactionId strings; use the format API with the correct delimiter","Validate delimiter count before parsing ids from external/log sources","Handle ids from older pinpoint versions or non-pinpoint sources separately"],"tags":["parsing","illegal-argument","transactionid"],"backgroundTag":"invalid-argument-format","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}