{"record":{"id":"5687b2bc418cc252","repo":"mastra-ai/mastra","slug":"the-cursor-cursor-looks-like-a-range-use-one","errorCode":null,"errorMessage":"The cursor \"${cursor}\" looks like a range. Use one of the individual message IDs as the cursor instead: start=\"${rangeIds.startId}\" or end=\"${rangeIds.endId}\".","messagePattern":"The cursor \"(.+?)\" looks like a range\\. Use one of the individual message IDs as the cursor instead: start=\"(.+?)\" or end=\"(.+?)\"\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/memory/src/tools/om-tools.ts","lineNumber":805,"sourceCode":"  nextCharOffset?: number;\n  note?: string;\n}> {\n  if (!memory || typeof memory.getMemoryStore !== 'function') {\n    throw new Error('Memory instance is required for recall');\n  }\n\n  if (!threadId) {\n    throw new Error('Thread ID is required for recall');\n  }\n\n  const resolved = await resolveCursorMessage(memory, cursor, {\n    resourceId,\n    threadScope,\n    enforceThreadScope: false,\n  });\n\n  if ('hint' in resolved) {\n    throw new Error(resolved.hint);\n  }\n\n  const allParts = formatMessageParts(resolved, 'high');\n\n  if (allParts.length === 0) {\n    throw new Error(\n      `Message ${cursor} has no visible content (it may be an internal system message). Try a neighboring message ID instead.`,\n    );\n  }\n\n  const target = [...allParts].reverse().find(p => p.partIndex === partIndex);\n\n  if (!target) {\n    const availableIndices = allParts.map(p => p.partIndex).join(', ');\n    const highestVisiblePartIndex = Math.max(...allParts.map(p => p.partIndex));\n\n    if (partIndex > highestVisiblePartIndex) {\n      const nextMessage = await getNextVisibleMessage({","sourceCodeStart":787,"sourceCodeEnd":823,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/tools/om-tools.ts#L787-L823","documentation":"Cursors must be a single message ID. `parseRangeFormat` detects range-shaped cursors like \"startId:endId\" or \"id1:id2,id3:id4\" (the internal format of merged ranges) and `resolveCursorMessage` returns a hint object; the detail-recall path converts that hint into this thrown error. The hint itself contains the correct start/end IDs to use instead.","triggerScenarios":"Passing a range cursor copied from internal/observational-memory state (e.g. \"msgA:msgB\") into the recall tool's cursor argument; an LLM echoing back a range it saw in tool output instead of one endpoint ID.","commonSituations":"Piping output from another om feature that emits ranges directly into recall; hand-building cursors by concatenating two IDs; model misreading the cursor documentation.","solutions":["Parse the error message: it names start=\"...\" and end=\"...\" — use one of those individual IDs as the cursor.","Use the start ID to recall forward from the beginning of the range, or the end ID to end at it.","Never pass multi-message range strings to the recall cursor parameter; ranges are internal to observational-memory processing.","If the model keeps doing this, add an example in the tool description showing a single plain message ID."],"exampleFix":"// before\nawait recallMessages({ memory, threadId, cursor: 'msg_1:msg_50' });\n// after\nawait recallMessages({ memory, threadId, cursor: 'msg_1' });","handlingStrategy":"validation","validationCode":"function isSingleMessageId(cursor: string): boolean {\n  return cursor.trim().length > 0 && !cursor.includes(':') && !cursor.includes(',');\n}\nif (!isSingleMessageId(cursor)) throw new Error('Use a single message ID, not a start:end range.');","typeGuard":null,"tryCatchPattern":"try {\n  return await recallDetail({ memory, threadId, cursor, partIndex });\n} catch (e) {\n  const m = e instanceof Error && /start=\"([^\"]+)\" or end=\"([^\"]+)\"/.exec(e.message);\n  if (m) {\n    return recallDetail({ memory, threadId, cursor: m[1], partIndex }); // use the start ID\n  }\n  throw e;\n}","preventionTips":["Only copy cursor values from recall responses' messageId fields.","Strip or reject ':' and ',' in cursors at your tool wrapper.","Document in the tool description that cursor is one message ID, never a range."],"tags":["memory","cursor","format","observational-memory"],"backgroundTag":"invalid-parameter-format","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}