{"record":{"id":"f81c42c9052bebc3","repo":"eyaltoledano/claude-task-master","slug":"invalid-run-id-id1","errorCode":null,"errorMessage":"Invalid run ID: ${id1}","messagePattern":"Invalid run ID: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/common/utils/run-id-generator.ts","lineNumber":117,"sourceCode":"\n/**\n * Compares two run IDs chronologically.\n * Returns a negative number if id1 is earlier, positive if id1 is later, or 0 if equal.\n * Can be used as a comparator function for Array.sort().\n *\n * @param {string} id1 - First run ID to compare\n * @param {string} id2 - Second run ID to compare\n * @returns {number} Negative if id1 < id2, positive if id1 > id2, zero if equal\n * @throws {Error} If either run ID is invalid\n *\n * @example\n * compareRunIds('2024-01-15T10:00:00.000Z', '2024-01-15T11:00:00.000Z') // returns negative number\n * ['2024-01-15T14:00:00.000Z', '2024-01-15T10:00:00.000Z'].sort(compareRunIds)\n * // returns ['2024-01-15T10:00:00.000Z', '2024-01-15T14:00:00.000Z']\n */\nexport function compareRunIds(id1: string, id2: string): number {\n\tif (!isValidRunId(id1)) {\n\t\tthrow new Error(`Invalid run ID: ${id1}`);\n\t}\n\n\tif (!isValidRunId(id2)) {\n\t\tthrow new Error(`Invalid run ID: ${id2}`);\n\t}\n\n\t// String comparison works for ISO 8601 timestamps\n\t// because they are lexicographically sortable\n\tif (id1 < id2) return -1;\n\tif (id1 > id2) return 1;\n\treturn 0;\n}\n","sourceCodeStart":99,"sourceCodeEnd":130,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/common/utils/run-id-generator.ts#L99-L130","documentation":"compareRunIds() is a chronological comparator for run IDs, which are ISO 8601 UTC timestamps (e.g. '2024-01-15T10:00:00.000Z'). It validates id1 via isValidRunId() before comparing and throws if id1 is not a valid timestamp string.","triggerScenarios":"Calling compareRunIds('run-123', validId) with a non-timestamp ID; sorting an array containing null/undefined/legacy IDs via [...ids].sort(compareRunIds); IDs produced by older versions of the generator with a different format.","commonSituations":"Mixing run IDs from different storage/backends or legacy formats; uninitialized array entries; hand-crafted IDs pasted from logs.","solutions":["Filter the collection before sorting: ids.filter(isValidRunId)","Regenerate the invalid ID with generateRunId()","Check the ID source — if legacy, migrate or parse with parseRunId() which returns null instead of throwing"],"exampleFix":"// before\nconst sorted = runs.map(r => r.id).sort(compareRunIds); // throws on bad id\n// after\nconst ids = runs.map(r => r.id).filter(isValidRunId);\nif (ids.length !== runs.length) console.warn('Dropped invalid run IDs');\nconst sorted = ids.sort(compareRunIds);","handlingStrategy":"validation","validationCode":"if (!isValidRunId(id1)) throw new Error(`Cannot compare invalid run ID: ${id1}`);\nconst sorted = ids.filter(isValidRunId).sort(compareRunIds);","typeGuard":"function isSortableRunId(id: unknown): id is string {\n  return typeof id === 'string' && isValidRunId(id);\n}","tryCatchPattern":"try {\n  return ids.sort(compareRunIds);\n} catch (err) {\n  if (err.message.startsWith('Invalid run ID')) {\n    console.warn('Dropping malformed run IDs:', err.message);\n    return ids.filter(isValidRunId).sort(compareRunIds);\n  }\n  throw err;\n}","preventionTips":["Always generate IDs with generateRunId(), never hand-format timestamps","Filter collections with isValidRunId before sorting","Use parseRunId() (returns null) when throw-free handling is preferred"],"tags":["validation","run-id","sorting"],"backgroundTag":"invalid-identifier-format","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}