mastra-ai/mastra · error · Error
${EXTRACTED_VALUES_TAG} must contain a JSON object.
Error message
${EXTRACTED_VALUES_TAG} must contain a JSON object. What it means
When the observer/reflector output contains an `<extracted-values>` block, Observational Memory parses its contents as a JSON object keyed by extractor slug. `parseExtractedValuesObject` throws this error when the tag's content is valid JSON but not an object — e.g. an array, string, number, or `null`. The error is recorded as a failure under the 'extracted-values' slug rather than crashing the stream.
Source
Thrown at packages/memory/src/processors/observational-memory/extractor.ts:292
failures.push(parsed.error.message);
}
throw new Error(`Extractor "${extractor.slug}" output did not match its schema: ${failures[0] ?? 'invalid value'}`);
}
export interface ParsedExtractedValues {
values: Record<string, unknown>;
failures: Array<{ slug: string; error: string }>;
}
function parseExtractedValuesObject(raw: string): Record<string, unknown> | undefined {
const trimmed = raw.trim();
if (!trimmed || trimmed.startsWith('Write only the extracted values JSON object here.')) {
return undefined;
}
const parsed = JSON.parse(trimmed) as unknown;
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
throw new Error(`${EXTRACTED_VALUES_TAG} must contain a JSON object.`);
}
return parsed as Record<string, unknown>;
}
export function parseExtractedValues(output: string, extractors: readonly Extractor<any>[]): ParsedExtractedValues {
const values: Record<string, unknown> = {};
const failures: Array<{ slug: string; error: string }> = [];
const inlineExtractors = extractors.filter(extractor => extractor.mode === 'inline');
const regex = new RegExp(`<${EXTRACTED_VALUES_TAG}>([\\s\\S]*?)<\\/${EXTRACTED_VALUES_TAG}>`, 'gi');
const matches = [...output.matchAll(regex)];
for (const match of matches) {
try {
const extractedValues = parseExtractedValuesObject(match[1] ?? '');
if (!extractedValues) {
continue;
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Strengthen extractor instructions to say 'Output a single JSON object whose keys are the extractor tags and whose values are the extracted values.'
- Post-process the model output before parsing (or rely on the recorded failure and retry the extraction pass).
- Use a stronger model for the reflector/observer if arrays persist.
- Catch failures via the ParsedExtractedValues.failures array and inject corrective feedback on retry.
Example fix
// model output before
<extracted-values>[{"user-goals":"run a marathon"}]</extracted-values>
// model output after
<extracted-values>{"user-goals":"run a marathon"}</extracted-values> Defensive patterns
Strategy: try-catch
Validate before calling
function isJsonObjectString(s) {
try { const v = JSON.parse(s); return v !== null && typeof v === 'object' && !Array.isArray(v); }
catch { return false; }
} Type guard
function isRecord(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); } Try / catch
const { values, failures } = parseExtractedValues(output, extractors);
const shapeFailures = failures.filter(f => f.slug === 'extracted-values');
if (shapeFailures.length) {
logger.warn('extracted-values block was not a JSON object; retrying extraction', { error: shapeFailures[0].error });
} Prevention
- Tell the model explicitly: 'inside <extracted-values>, output exactly one JSON object, never an array'.
- Include a one-line example object in the extraction prompt.
- Treat 'extracted-values' failures from parseExtractedValues as a retry signal with corrective feedback.
When it happens
Trigger: Model emits a JSON array `[...]` inside <extracted-values> instead of an object; model emits a bare string or number; model wraps a JSON array of {slug,value} pairs; JSON.stringify of an array being echoed back by the model.
Common situations: Models that interpret 'extracted values' as a list rather than a map; prompts with multiple extractors leading the model to output an array of records; weak models ignoring the object-shape instruction.
Related errors
- Failed to parse working memory input as JSON: ${errorMessage
- Failed to parse A2A stream event: ${error instanceof Error ?
- Linear cursor is invalid.
- Extractor "${extractor.slug}" output did not match its schem
- Observer produced degenerate output after retry. ${describeD
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4cef1eda812fabab.
Report an issue: GitHub.