mastra-ai/mastra · error · Error
Hook extractor "${name}" cannot include instructions or a sc
Error message
Hook extractor "${name}" cannot include instructions or a schema. What it means
Hook extractors run after observation without contributing to the extraction prompt, so `instructions` and `schema` are meaningless (and misleading) for them. The library throws this in the constructor when `mode: 'hook'` is combined with either `config.instructions` or `config.schema` set.
Source
Thrown at packages/memory/src/processors/observational-memory/extractor.ts:158
const name = config.name.trim();
const instructions = typeof config.instructions === 'string' ? config.instructions.trim() : undefined;
const slug = slugifyExtractorName(name);
const isHook = config.mode === 'hook';
if (!name) {
throw new Error('Extractor name is required.');
}
if (!isHook && !config.instructions) {
throw new Error(`Extractor "${name}" must include instructions.`);
}
if (instructions !== undefined && !instructions) {
throw new Error(`Extractor "${name}" must include instructions.`);
}
if (isHook && !config.onExtracted) {
throw new Error(`Hook extractor "${name}" must include an onExtracted handler.`);
}
if (isHook && (config.instructions || config.schema)) {
throw new Error(`Hook extractor "${name}" cannot include instructions or a schema.`);
}
assertValidSlug(slug, name);
if (!internal && RESERVED_XML_TAGS.has(slug)) {
throw new Error(`Extractor slug "${slug}" is reserved by Observational Memory.`);
}
this.name = name;
this.slug = slug;
this.instructionsConfig = config.instructions ?? '';
this.schemaConfig = config.schema;
this.instructions = instructions ?? '';
this.schema = (
isHook ? z.unknown() : typeof config.schema === 'function' ? z.string() : (config.schema ?? z.string())
) as z.ZodType<T>;
this.mode = isHook ? 'hook' : internal || !config.schema ? 'inline' : 'structured';
this.includePreviousExtraction = isHook ? false : (config.includePreviousExtraction ?? true);
this.metadataKeyPath = isHook ? false : (config.metadataKeyPath ?? `extracted.${slug}`);
this.onExtracted = config.onExtracted;View on GitHub (pinned to 75dd419e61)
Solutions
- Remove `instructions` and `schema` from the hook extractor config.
- If you need prompt-driven or schema-validated extraction, drop `mode: 'hook'` and keep instructions/schema instead.
- Move any transformation logic into `onExtracted`, which is the only work surface for hook extractors.
Example fix
// before
new Extractor({ name: 'Audit', mode: 'hook', schema: z.string() });
// after
new Extractor({
name: 'Audit',
mode: 'hook',
onExtracted: ({ current }) => current,
}); Defensive patterns
Strategy: validation
Validate before calling
if (config.mode === 'hook' && (config.instructions || config.schema)) {
throw new Error(`Hook extractor "${config.name}" must not define instructions/schema`);
} Type guard
function isCleanHookConfig(c) {
return c.mode !== 'hook' || (c.instructions === undefined && c.schema === undefined);
} Try / catch
try {
const extractor = new Extractor(config);
} catch (e) {
if (e.message.includes('cannot include instructions or a schema')) {
logger.error('Hook extractor has prompt-only fields set', { name: config.name });
} else { throw e; }
} Prevention
- When converting an extractor to hook mode, delete instructions and schema explicitly.
- Keep hook and prompt extractor configs as separate factory functions so fields can't leak across.
- Review spread-based config composition for leftover prompt fields.
When it happens
Trigger: new Extractor({ name: 'X', mode: 'hook', instructions: '...' }); new Extractor({ name: 'X', mode: 'hook', schema: z.string() }); leaving `instructions`/`schema` in a shared config object when switching an extractor to hook mode.
Common situations: Converting an existing inline/structured extractor to hook mode by only toggling mode; spreading a base config containing instructions/schema into a hook extractor; TypeScript types allow it because fields are optional.
Related errors
- Extractor "${name}" must include instructions.
- Hook extractor "${name}" must include an onExtracted handler
- ModelByInputTokens requires at least one threshold in "upTo"
- ModelByInputTokens threshold keys must be positive numbers.
- ModelByInputTokens requires a valid model target for thresho
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/cb0507ed70204bfb.
Report an issue: GitHub.