mastra-ai/mastra · error
Factory review phase requires a controller request context.
Error message
Factory review phase requires a controller request context.
What it means
reviewRuntimeFromRequestContext builds the runtime snapshot for the Factory review phase from the incoming request context. Wake/kickoff dispatch must run under a controller request context that carries the agent controller session; if requestContext is missing or lacks a .get function, the library cannot resolve the controller session, so it throws before any model work begins. Callers (e.g. the 'value' state computer) must supply the server request context.
Source
Thrown at mastracode/factory/src/rules/processor.ts:98
type ActivePhaseSnapshotBase = {
bindingId: string;
itemId: string;
revision: number;
stage: FactoryRuleStage;
role: string;
ruleSetVersion: string;
status: 'active';
};
type ActivePhaseSnapshotValue =
| (ActivePhaseSnapshotBase & { board: 'work' })
| (ActivePhaseSnapshotBase & { board: 'review' } & RuntimeSnapshot);
type PhaseSnapshotValue = ActivePhaseSnapshotValue | { bindingId?: string; status: 'none' };
function reviewRuntimeFromRequestContext(requestContext: ComputeStateSignalArgs['requestContext']): RuntimeSnapshot {
if (!requestContext || typeof requestContext.get !== 'function') {
throw new Error('Factory review phase requires a controller request context.');
}
const context = requestContext.get<'controller', AgentControllerRequestContext<MastraCodeState>>('controller');
const modelId = context?.session?.modelId.trim();
if (!modelId) {
throw new Error('Factory review phase requires a selected session model.');
}
return { modelId, thinkingLevel: resolveRequestThinkingLevel(context) };
}
function workItemSourceKey(item: WorkItemRow): string | null {
const source = item.externalSource;
return source ? `${source.integrationId}:${source.type}:${source.externalId}` : null;
}
function boardForItem(item: WorkItemRow): FactoryRuleBoard {
return item.externalSource?.type === 'pull-request' ? 'review' : 'work';
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Invoke the review phase only through the agent request path that provides RequestContext, and set the 'controller' entry on it.
- In tests/background jobs, construct and pass a real RequestContext (requestContext.set('controller', ...)) instead of undefined.
- Check the call site populating ComputeStateSignalArgs.requestContext and restore propagation if it was dropped.
- Ensure any context adapter/wrapper still exposes the .get method expected by the processor.
Example fix
// before: calling the state computer without a request context
const snapshot = await computeState({ args: { ...args, requestContext: undefined } });
// after: pass the controller request context
const requestContext = new RequestContext();
requestContext.set('controller', controllerContext);
const snapshot = await computeState({ args: { ...args, requestContext } }); Defensive patterns
Strategy: validation
Validate before calling
if (!requestContext || typeof requestContext.get !== 'function') {
throw new Error('review phase requires a controller request context');
}
const ctx = requestContext.get('controller');
if (!ctx) throw new Error('controller context not set on request context'); Type guard
function hasRequestContext(rc) {
return !!rc && typeof rc.get === 'function';
} Try / catch
try {
const snapshot = reviewRuntimeFromRequestContext(requestContext);
} catch (e) {
if (String(e?.message).includes('requires a controller request context')) {
// build and attach the RequestContext before retrying
const rc = new RequestContext();
rc.set('controller', controllerContext);
return reviewRuntimeFromRequestContext(rc);
} else throw e;
} Prevention
- Only invoke review-phase compute paths from the agent request pipeline that supplies RequestContext
- In tests, construct a real RequestContext with the controller entry instead of stubs
- Keep ComputeStateSignalArgs.requestContext propagation intact through wrappers/adapters
- Add an early assert for requestContext presence at API boundaries
When it happens
Trigger: The review-phase processor was invoked without a requestContext at all, or with an object that isn't a RequestContext (no .get method) — e.g. calling the compute-state 'value' signal directly, from a background job, or in a test with a bare context.
Common situations: Invoking the review processor from scripts/tests without constructing RequestContext; wiring the processor into a path that doesn't propagate the HTTP request context; refactors that changed the context shape passed to ComputeStateSignalArgs.
Related errors
- Factory review phase requires a selected session model.
- connect({ id, name }): "name" is required when connecting wi
- MemoryThread.${methodName}() requires an agentId. Pass it vi
- @mastra/livekit: reply generation runs through the Mastra ag
- @mastra/livekit: MastraVoiceAgent requires `agent` or `gener
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/e0cfdd5168b73113.
Report an issue: GitHub.