github/copilot-sdk · error
Invalid factory handle
Error message
Invalid factory handle
What it means
getFactoryDefinition looks up the StoredFactory registered for a given FactoryHandle in an internal map; if the handle is not registered in this process, it throws 'Invalid factory handle'. Handles are produced by defineFactory, so this error indicates the handle was not created by this library in the current process or was corrupted/mistyped.
Solutions
- Recreate the handle by calling defineFactory in the current process and use the returned handle.
- Fix hot-reload flows so consumers re-acquire handles after the module is replaced.
- Ensure only one copy of the library is installed/loaded; deduplicate node_modules.
- In JavaScript callers, verify the handle comes from defineFactory's return value and is not undefined/null.
Example fix
// before const handle = getHandleFromCache(); // stale after reload const def = definition(handle); // after const handle = defineFactory(factoryMeta); // recreate in current process const def = definition(handle);
Defensive patterns
Strategy: try-catch
Validate before calling
if (handle == null) throw new TypeError('Factory handle is missing — use the value returned by defineFactory'); Type guard
function isFactoryHandle(h) { return typeof h === 'object' && h !== null; } Try / catch
let def;
try {
def = definition(handle);
} catch (e) {
if (e.message === 'Invalid factory handle') {
handle = defineFactory(factoryMeta); // re-acquire after hot reload
def = definition(handle);
} else throw e;
} Prevention
- Always keep handles in module scope of the module that created them
- Re-create handles after dev-server hot reload
- Never serialize or pass handles across process/worker boundaries
- Ensure only one copy of the library is installed
When it happens
Trigger: Passing a handle from a different process/module instance (e.g. after hot-reload replaced the module and its factoryHandles map), a fabricated or deserialized handle, or a wrong/undefined value passed where a FactoryHandle is expected (e.g. to name(handle) or definition(handle)).
Common situations: Dev-server hot module replacement invalidating previously created handles; serializing a handle across a worker/process boundary; mixing two copies of the library (duplicate installs); passing a null/undefined or string handle from untyped JavaScript.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- An in-process FFI runtime library is already loaded from
- Cannot log after the factory run has settled
- CLI child process was unexpectedly started in parent…
- CLI process not started
- CLI process not started
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/14e17ad3dbb701cf.
Report an issue: GitHub.
Appendix: source
Thrown at nodejs/src/factory.ts:507
const meta = deepFreeze(structuredClone(definition.meta));
validateLimits(meta);
validatePhases(meta);
const stored: StoredFactory = {
meta,
run: definition.run,
};
const handle = Object.freeze({ meta }) as unknown as FactoryHandle<TArgs, TResult>;
factoryHandles.set(handle, stored);
return handle;
}
/** @internal */
export function getFactoryDefinition(handle: FactoryHandle): StoredFactory {
const definition = factoryHandles.get(handle);
if (!definition) {
throw new Error("Invalid factory handle");
}
return definition;
}
View on GitHub (pinned to cd8cf15dc3)