github/copilot-sdk · error
factory.run and factory.resume are not allowed while a…
Error message
factory.run and factory.resume are not allowed while a factory body is running on this call path.
What it means
The SDK tracks, per async call path via AsyncLocalStorage, whether a factory body (the callback passed to a factory-producing method) is currently executing. Calling factory.run or factory.resume re-entrantly from inside such a body would corrupt execution state, so the library throws this guard error instead.
Solutions
- Do not call run/resume from within the factory body; return/complete the body first.
- Move the nested run/resume call outside the factory callback (e.g. after the awaited result).
- If a nested execution is genuinely needed, escape the async context so the guard doesn't see the active store — but prefer restructuring instead.
- Register a separate top-level factory rather than reusing the running one recursively.
Example fix
// before
const factory = session.factory();
await factory.run(async () => {
await factory.resume(); // throws: re-entrant
});
// after
const factory = session.factory();
const result = await factory.run(async () => {
/* body work only */
});
await factory.resume(); // outside the body Defensive patterns
Strategy: try-catch
Validate before calling
// don't call run/resume from inside a factory body; restructure the code instead
Try / catch
try {
await factory.run(body);
} catch (e) {
if (e.message.includes('not allowed while a factory body is running')) {
// move the nested run/resume outside the body
} else throw e;
} Prevention
- Keep factory bodies free of re-entrant run/resume calls.
- Resume only after run's promise settles.
- Register follow-up work outside the body (after await) rather than inside callbacks sharing the async context.
When it happens
Trigger: Calling factory.run() or factory.resume() synchronously (or within an awaited chain on the same async context) inside a factory body — i.e. the run/resume call originates from the callback that is itself being driven by the factory.
Common situations: Recursive factory logic, calling run/resume from event handlers registered inside the factory body that execute on the same async context, misusing resume in place of returning a value from the body.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- The in-process runtime connection is closed.
- CLI process not started
- CLI child process was unexpectedly started in parent…
- Server port not available
- Session not found
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/7e9534148e82dce9.
Report an issue: GitHub.
Appendix: source
Thrown at nodejs/src/session.ts:115
);
}
function copyDefinedFactoryAgentOption<TKey extends keyof FactoryAgentOptions>(
source: FactoryAgentOptions,
target: FactoryAgentOptions,
key: TKey
): void {
const value = source[key];
if (value !== undefined) {
target[key] = value;
}
}
const factoryExecutionStore = new AsyncLocalStorage<{ active: boolean }>();
function throwIfFactoryExecutionIsActive(): void {
if (factoryExecutionStore.getStore()?.active) {
throw new Error(
"factory.run and factory.resume are not allowed while a factory body is running on this call path."
);
}
}
/**
* Convert a raw hook input received over the wire into its public-facing shape.
* This deserializes the numeric Unix-ms `timestamp` field on BaseHookInput
* into a Date and maps the wire `cwd` field to `workingDirectory`.
*/
function deserializeHookInput(raw: unknown): unknown {
if (
!raw ||
typeof raw !== "object" ||
typeof (raw as { timestamp?: unknown }).timestamp !== "number"
) {
return raw;
}View on GitHub (pinned to cd8cf15dc3)