{"record":{"id":"b012fe9462eebcc6","repo":"mastra-ai/mastra","slug":"processor-returned-external-message-list-b012fe","errorCode":"PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST","errorMessage":"Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.","messagePattern":"Processor (.+?) returned a MessageList instance other than the one passed in\\. Use the messageList argument instead\\.","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"packages/core/src/workflows/evented/workflow.ts","lineNumber":1193,"sourceCode":"                  text: `Processor ${processor.id} requires messageList or messages for processInput phase`,\n                });\n              }\n\n              // Create source checker before processing to preserve message sources\n              const idsBeforeProcessing = (messages as MastraDBMessage[]).map(m => m.id);\n              const check = passThrough.messageList.makeMessageSourceChecker();\n\n              const result = await processor.processInput({\n                ...baseContext,\n                messages: messages as MastraDBMessage[],\n                messageList: passThrough.messageList,\n                systemMessages: (systemMessages ?? []) as CoreMessage[],\n              });\n\n              if (result instanceof MessageList) {\n                // Validate same instance\n                if (result !== passThrough.messageList) {\n                  throw new MastraError({\n                    category: ErrorCategory.USER,\n                    domain: ErrorDomain.MASTRA_WORKFLOW,\n                    id: 'PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST',\n                    text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`,\n                  });\n                }\n                return {\n                  ...passThrough,\n                  messages: result.get.all.db(),\n                  systemMessages: result.getSystemMessages(),\n                };\n              } else if (Array.isArray(result)) {\n                // Processor returned an array of messages\n                ProcessorRunner.applyMessagesToMessageList(\n                  result as MastraDBMessage[],\n                  passThrough.messageList,\n                  idsBeforeProcessing,\n                  check,","sourceCodeStart":1175,"sourceCodeEnd":1211,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workflows/evented/workflow.ts#L1175-L1211","documentation":"After processInput runs, if the processor returns a MessageList, the adapter verifies it is the SAME instance that was passed in. Returning a different MessageList would orphan conversation state, so the adapter throws PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST, instructing you to mutate the provided messageList argument instead of constructing/returning a new one.","triggerScenarios":"A processInput implementation that creates a new MessageList (e.g. new MessageList(otherMessages) or MessageList.from(...)) and returns it, rather than mutating the messageList parameter and returning it.","commonSituations":"Migrating processors from older (messages-in/messages-out) APIs; copying messages into a fresh MessageList 'for safety'; factory helpers that always build new MessageList instances.","solutions":["Mutate the messageList passed into processInput (e.g. messageList.add/remove) and return that same instance (or return nothing non-MessageList).","Remove any new MessageList(...) / clone logic from the processor body.","If transformation is needed, apply it to the existing MessageList via its API instead of rebuilding one."],"exampleFix":"// before\nasync processInput({ messageList }) {\n  const copy = new MessageList(messageList.get.all());\n  copy.add(systemMsg);\n  return copy;\n}\n\n// after\nasync processInput({ messageList }) {\n  messageList.add(systemMsg);\n  return messageList;\n}","handlingStrategy":"validation","validationCode":"function checkProcessorReturn(ret: unknown, passed: MessageList) {\n  if (ret instanceof MessageList && ret !== passed) {\n    throw new Error('Processor returned a different MessageList; mutate the passed-in one instead');\n  }\n}","typeGuard":"const returnsSameList = (ret: unknown, passed: MessageList): boolean =>\n  !(ret instanceof MessageList) || ret === passed;","tryCatchPattern":"try {\n  await runProcessorStep();\n} catch (e) {\n  if (e instanceof MastraError && e.id === 'PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST') {\n    // fix the processor to mutate the given messageList\n  }\n  throw e;\n}","preventionTips":["Treat the messageList argument as the single source of truth: mutate, never clone.","Code-review processors for `new MessageList(` usage inside processInput/processOutputResult.","Add a lint rule or unit test asserting processors return the same MessageList instance they receive."],"tags":["processor","messagelist","immutability","workflow"],"backgroundTag":"processor-returned-external-messagelist","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}