{"record":{"id":"e432e5463ca841af","repo":"mastra-ai/mastra","slug":"custom-subconscious-observation-agent-name-re","errorCode":null,"errorMessage":"Custom Subconscious observation agent \"${name}\" requires schema and onExtracted.","messagePattern":"Custom Subconscious observation agent \"(.+?)\" requires schema and onExtracted\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/memory/src/processors/observational-memory/subconscious/index.ts","lineNumber":219,"sourceCode":"          throw new Error('Subconscious capture shares the Observer model and does not accept model or maxSteps.');\n        }\n        if (\n          'schema' in entry &&\n          entry.schema &&\n          (!('onExtracted' in entry) || typeof entry.onExtracted !== 'function')\n        ) {\n          throw new Error('A custom capture schema requires an onExtracted hook that handles its output.');\n        }\n      }\n      return;\n    }\n    if ('model' in entry || 'maxSteps' in entry) {\n      throw new Error(\n        `Subconscious observation extractor \"${name}\" shares the Observer model and does not accept model or maxSteps.`,\n      );\n    }\n    if (!('schema' in entry) || !entry.schema || !('onExtracted' in entry) || typeof entry.onExtracted !== 'function') {\n      throw new Error(`Custom Subconscious observation agent \"${name}\" requires schema and onExtracted.`);\n    }\n  }\n\n  #validateReflectionEntry(entry: SubconsciousReflectionEntry): void {\n    const name = entryName(entry);\n    if (typeof entry === 'string') {\n      if (!BUILT_IN_REFLECTION.has(name)) throw new Error(`Unknown Subconscious reflection agent: ${name}`);\n      return;\n    }\n    if (BUILT_IN_REFLECTION.has(name) && 'agent' in entry && entry.agent) {\n      throw new Error(`Built-in Subconscious reflection agent \"${name}\" cannot be replaced with a custom agent.`);\n    }\n    if (!BUILT_IN_REFLECTION.has(name) && !entry.instructions?.trim() && !('agent' in entry && entry.agent)) {\n      throw new Error(`Custom Subconscious reflection agent \"${name}\" requires instructions or agent.`);\n    }\n  }\n}\n","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/processors/observational-memory/subconscious/index.ts#L201-L237","documentation":"A custom observation extractor must be fully specified: it needs a schema describing what to extract and an onExtracted function to consume the result. If either is missing, falsy, or onExtracted is not a function, the constructor throws. Strings are reserved for built-in agents, so custom names must be objects.","triggerScenarios":"new Subconscious({ observation: [{ name: 'my-agent' }] }) (no schema/onExtracted), or { name: 'my-agent', schema: null, onExtracted: 'notAFunction' }.","commonSituations":"Passing just a name expecting the library to infer behavior; spreading partial config where schema/onExtracted end up undefined; using a custom name as a string (custom names are never valid strings).","solutions":["Provide both schema (a Zod/JSON schema) and onExtracted (a function) on the entry object.","If you meant a built-in agent, use its exact built-in string name instead.","Verify the schema is truthy and onExtracted is typeof 'function' after any config spreading/merging."],"exampleFix":"// before\nnew Subconscious({ observation: [{ name: 'preferences' }] });\n// after\nnew Subconscious({ observation: [{ name: 'preferences', schema: PrefsSchema, onExtracted: async (p) => store(p) }] });","handlingStrategy":"validation","validationCode":"function customExtractorIsValid(e: { schema?: unknown; onExtracted?: unknown }): boolean {\n  return !!e.schema && typeof e.onExtracted === 'function';\n}\nif (!customExtractorIsValid(myExtractor)) throw new Error('custom extractor needs schema + onExtracted');","typeGuard":"function isCompleteExtractor(e: unknown): e is { name: string; schema: unknown; onExtracted: (r: unknown) => unknown } {\n  const o = e as Record<string, unknown> | null;\n  return !!o && !!o.schema && typeof o.onExtracted === 'function';\n}","tryCatchPattern":"try {\n  sub = new Subconscious({ observation: [entry] });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('requires schema and onExtracted')) {\n    console.error('Extractor entry is incomplete');\n  } else throw e;\n}","preventionTips":["Never pass bare custom names as strings; strings are built-ins only.","Build extractors via a typed helper that enforces schema + onExtracted.","Watch for spread/merge operations dropping fields.","Add a construction smoke test per extractor."],"tags":["configuration","validation","schema"],"backgroundTag":"missing-required-field","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}