mastra-ai/mastra · error
Reflector produced empty output after ${attemptNumber} attem
Error message
Reflector produced empty output after ${attemptNumber} attempt(s)${parsed.degenerate ? ' (degenerate repetition)' : ''} — refusing to commit an empty reflection over ${originalTokens} observation tokens What it means
After exhausting the reflection ladder, if the model returned empty or degenerate (repetitive) observations for non-empty input, the reflector throws instead of committing. Committing empty output would silently wipe the active observations slice, so this is a hard safety guard.
Source
Thrown at packages/memory/src/processors/observational-memory/reflector-runner.ts:572
config: this.getObservationMarkerConfig(),
});
streamContext.startedAt = startMarker.data.startedAt;
// Stream OM lifecycle markers as transient so the OutputWriter does not persist standalone data-only messages; OM persists the durable marker explicitly.
await streamContext.writer.custom({ ...startMarker, transient: true }).catch(() => {});
await this.persistMarkerToStorage(startMarker, streamContext.threadId, streamContext.resourceId);
}
currentLevel = Math.min(currentLevel + 1, maxLevel) as CompressionLevel;
}
// A reflection of non-empty observations must never come back empty: the
// caller commits the result as the new activeObservations (sync path) or
// as the bufferedReflection replacing the reflected slice (buffered path),
// so returning '' here silently wipes memory. Empty output only happens
// when every ladder attempt was degenerate (parseReflectorOutput discards
// degenerate text) or the model returned nothing — both are failures.
if (observations.trim().length > 0 && parsed.observations.trim().length === 0) {
throw new Error(
`Reflector produced empty output after ${attemptNumber} attempt(s)${parsed.degenerate ? ' (degenerate repetition)' : ''} — refusing to commit an empty reflection over ${originalTokens} observation tokens`,
);
}
const structuredExtraction = await extractStructuredValues({
agent,
source: 'reflector',
extractors: activeExtractors,
memory: temporaryMemory?.options,
priorExtractedValues,
requestContext: internalRequestContext,
observabilityContext,
abortSignal,
});
const parsedExtractedValues = mergeExtractedValues(parsed.extractedValues, structuredExtraction.values);
const parsedExtractionFailures = mergeExtractionFailures(parsed.extractionFailures, structuredExtraction.failures);
const hookedValues = await applyExtractorHooks({
source: 'reflector',View on GitHub (pinned to 75dd419e61)
Solutions
- Use a stronger model for the reflector (check reflector model config in ObservationalMemory options)
- Review the reflector prompt/instructions for token limits or constraints causing empty replies
- Reduce the observation batch size so the reflection fits within the model's output budget
- Retry the reflection — transient model failures may resolve on a later call
Example fix
// before
new ObservationalMemory({ reflector: { model: 'tiny-model' } })
// after
new ObservationalMemory({ reflector: { model: 'openai/gpt-4o' } }) Defensive patterns
Strategy: retry
Validate before calling
const obs = observations.trim(); if (!obs) return; // nothing to reflect
Type guard
const isEmptyReflection = (out: string) => out.trim().length === 0;
Try / catch
try { result = await reflect(...) } catch (e) { if (String(e).includes('empty output')) { logAndRetryOrSkip(e); } else throw e; } Prevention
- Configure a capable model for the reflector
- Keep reflection input within model output budget
- Monitor for degenerate repetition and alert
- Retry reflections on transient failures
When it happens
Trigger: All retry/ladder attempts of the reflector agent produced whitespace-only or degenerate repetition output while the original observation tokens were non-empty (observations.trim().length > 0 but parsed.observations empty).
Common situations: Misconfigured/low-quality model for the reflector; model hitting token limits and returning nothing; model loops producing degenerate repetition; reflector agent prompt overridden incorrectly.
Related errors
- MastraClient.deleteThread() requires exactly one of agentId
- No response body
- @mastra/livekit: reply generation runs through the Mastra ag
- @mastra/opencode: failed to initialize memory storage from $
- Failed to rename session (${res.status})
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/40130a5d94b57d6e.
Report an issue: GitHub.