{"record":{"id":"3e6437e7b6d51d87","repo":"mastra-ai/mastra","slug":"turn-not-started-call-start-first","errorCode":null,"errorMessage":"Turn not started — call start() first","messagePattern":"Turn not started — call start\\(\\) first","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/memory/src/processors/observational-memory/observation-turn/turn.ts","lineNumber":114,"sourceCode":"    this.threadId = opts.threadId;\n    this.resourceId = opts.resourceId;\n    this.messageList = opts.messageList;\n    this.agent = opts.agent;\n    this.sendSignal = opts.sendSignal;\n    this.sendStateSignal = opts.sendStateSignal;\n    this.requestContext = opts.requestContext;\n    this.observabilityContext = opts.observabilityContext;\n    this.hooks = opts.hooks ?? {};\n  }\n\n  readonly om: ObservationalMemory;\n  readonly threadId: string;\n  readonly resourceId: string | undefined;\n  readonly messageList: MessageList;\n\n  /** The current cached record. Refreshed after mutations (activate/observe/reflect). */\n  get record(): ObservationalMemoryRecord {\n    if (!this._record) throw new Error('Turn not started — call start() first');\n    return this._record;\n  }\n\n  /** The context loaded during start(). */\n  get context(): TurnContext {\n    if (!this._context) throw new Error('Turn not started — call start() first');\n    return this._context;\n  }\n\n  /** The current step, if one exists. */\n  get currentStep(): ObservationStep | undefined {\n    return this._currentStep;\n  }\n\n  addHooks(hooks?: ObservationTurnHooks): void {\n    if (!hooks) return;\n    Object.assign(this.hooks, hooks);\n  }","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/processors/observational-memory/observation-turn/turn.ts#L96-L132","documentation":"Turn.record is a cached memory record that is only created during start(). Accessing record before start() means the turn has no loaded record, so the getter throws to enforce the start() -> use lifecycle.","triggerScenarios":"Reading `turn.record` after constructing `new ObservationTurn(...)` but before `await turn.start(...)` completes.","commonSituations":"Logging the record at turn setup; a consumer that inspects the record for telemetry before the turn is started; forgetting to await start() (floating promise) and reading record immediately after.","solutions":["Call `await turn.start(memory, runState)` before reading turn.record","Check the private _started flag / restructure so record access happens in code paths after start()","If you only need the record outside a turn, call om.getOrCreateRecord(threadId, resourceId) directly"],"exampleFix":"// before\nconst turn = new ObservationTurn(om, threadId, resourceId, messageList);\nconsole.log(turn.record); // throws\n// after\nconst turn = new ObservationTurn(om, threadId, resourceId, messageList);\nawait turn.start();\nconsole.log(turn.record); // ok","handlingStrategy":"type-guard","validationCode":"// only access record after start() has resolved\nawait turn.start(memory);\nconst rec = turn.record;","typeGuard":"// ObservationTurn exposes no public started flag; gate by tracking start yourself\nlet started = false;\nfunction turnStarted(t: ObservationTurn): boolean { return started; }\n// set started = true after `await turn.start(...)` resolves","tryCatchPattern":"let record: ObservationalMemoryRecord;\ntry {\n  record = turn.record;\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Turn not started')) {\n    await turn.start();\n    record = turn.record;\n  } else throw e;\n}","preventionTips":["Always await turn.start() immediately after constructing a turn","Read record only in code paths that run post-start","Use the TurnContext returned by start() where possible"],"tags":["observational-memory","lifecycle","state"],"backgroundTag":"method-called-out-of-order","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}