{"record":{"id":"b81c9bf915caeeae","repo":"mastra-ai/mastra","slug":"thread-cloning-is-not-implemented-by-this-storage","errorCode":null,"errorMessage":"Thread cloning is not implemented by this storage adapter (${this.constructor.name}). The cloneThread method needs to be implemented in the storage adapter.","messagePattern":"Thread cloning is not implemented by this storage adapter \\((.+?)\\)\\. The cloneThread method needs to be implemented in the storage adapter\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/memory/base.ts","lineNumber":185,"sourceCode":"   * List threads with optional filtering by resourceId and metadata.\n   *\n   * @param args - Filter, pagination, and ordering options\n   * @param args.filter - Optional filters for resourceId and/or metadata\n   * @param args.filter.resourceId - Optional resource ID to filter by\n   * @param args.filter.metadata - Optional metadata key-value pairs to filter by (AND logic)\n   * @returns Paginated list of threads matching the filters\n   */\n  abstract listThreads(args: StorageListThreadsInput): Promise<StorageListThreadsOutput>;\n\n  /**\n   * Clone a thread and its messages to create a new independent thread.\n   * The cloned thread will have clone metadata stored in its metadata field.\n   *\n   * @param args - Clone configuration options\n   * @returns The newly created thread and the cloned messages\n   */\n  async cloneThread(_args: StorageCloneThreadInput): Promise<StorageCloneThreadOutput> {\n    throw new Error(\n      `Thread cloning is not implemented by this storage adapter (${this.constructor.name}). ` +\n        `The cloneThread method needs to be implemented in the storage adapter.`,\n    );\n  }\n\n  async getResourceById(_: { resourceId: string }): Promise<StorageResourceType | null> {\n    throw new Error(\n      `Resource working memory is not implemented by this storage adapter (${this.constructor.name}). ` +\n        `This is likely a bug - all Mastra storage adapters should implement resource support. ` +\n        `Please report this issue at https://github.com/mastra-ai/mastra/issues`,\n    );\n  }\n\n  async saveResource(_: { resource: StorageResourceType }): Promise<StorageResourceType> {\n    throw new Error(\n      `Resource working memory is not implemented by this storage adapter (${this.constructor.name}). ` +\n        `This is likely a bug - all Mastra storage adapters should implement resource support. ` +\n        `Please report this issue at https://github.com/mastra-ai/mastra/issues`,","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/memory/base.ts#L167-L203","documentation":"cloneThread is an optional adapter capability; the base class default throws because thread cloning (copying a thread plus its messages with clone metadata) must be implemented by the concrete adapter. The active adapter has not implemented it.","triggerScenarios":"Calling cloneThread(args) (e.g. from memory/fork-thread flows) against an adapter that doesn't override cloneThread, such as a minimal custom store or an in-memory store.","commonSituations":"Forking a conversation thread in dev with a stub storage backend; custom adapters missing newer optional methods; third-party adapters lagging the core API.","solutions":["Use an adapter that implements cloneThread","Implement cloneThread in your adapter (copy thread row with clone metadata plus all messages)","Fork at the application level by manually creating a new thread and re-inserting messages"],"exampleFix":"// before\nawait storage.cloneThread({ threadId, newResourceId }); // throws\n// after\n// app-level fork, or implement in the adapter:\nasync cloneThread(args) { /* insert cloned thread + messages */ }","handlingStrategy":"fallback","validationCode":"function supportsCloneThread(storage: unknown): boolean {\n  return typeof (storage as any)?.cloneThread === 'function' &&\n    (storage as any).cloneThread !== (MastraStorage.prototype as any).cloneThread;\n}","typeGuard":"function canCloneThread(s: unknown): s is { cloneThread(a: StorageCloneThreadInput): Promise<StorageCloneThreadOutput> } {\n  return supportsCloneThread(s);\n}","tryCatchPattern":"try {\n  return await storage.cloneThread(args);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Thread cloning is not implemented')) {\n    return manualCloneThread(args); // app-level fork: new thread + copied messages\n  }\n  throw e;\n}","preventionTips":["Detect cloneThread support before offering fork-thread UI","Pick adapters known to implement cloning for fork-heavy workloads","Keep custom adapters implementing newer optional domain methods"],"tags":["storage","unsupported-operation","memory"],"backgroundTag":"method-not-implemented-by-adapter","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}