can1357/oh-my-pi · error · Error
options.authStorage and options.modelRegistry.authStorage mu
Error message
options.authStorage and options.modelRegistry.authStorage must be the same instance when both are provided
What it means
When constructing the executor, if the caller supplies both options.authStorage and options.modelRegistry, the code derives authStorage from modelRegistry and verifies identity. Passing two different AuthStorage instances is ambiguous (two sources of truth for credentials), so it throws.
Source
Thrown at packages/coding-agent/src/task/executor.ts:2975
// Launch-latency phase marks (performance.now()); read by the debug log
// emitted before this closure returns. Left undefined when setup throws
// before reaching the phase, which itself localizes the cost.
const perfStart = performance.now();
let resolvedAt: number | undefined;
let sessionOpenedAt: number | undefined;
let sessionCreatedAt: number | undefined;
let readyAt: number | undefined;
try {
checkAbort();
// Pin authStorage to modelRegistry.authStorage — mirrors the createAgentSession invariant.
const registryFromParent = options.modelRegistry !== undefined;
const modelRegistry =
options.modelRegistry ??
new ModelRegistry(options.authStorage ?? (await awaitAbortable(discoverAuthStorage())));
const authStorage = modelRegistry.authStorage;
if (options.authStorage && options.authStorage !== authStorage) {
throw new Error(
"options.authStorage and options.modelRegistry.authStorage must be the same instance when both are provided",
);
}
checkAbort();
if (!registryFromParent) {
modelRegistry.refreshInBackground();
} else {
logger.debug("runSubagent: reusing parent modelRegistry; skipping refresh");
}
checkAbort();
const configuredModelPatterns = resolveConfiguredModelPatterns(modelPatterns, settings);
const inheritedRetryFallbackChain =
configuredModelPatterns.length === 1
? resolveSubagentInheritedRetryFallbackChain(
subagentSettings,
modelRegistry,
modelRole ?? resolveExplicitModelRole(modelPatterns, subagentSettings),View on GitHub (pinned to 9690622007)
Solutions
- Pass only options.modelRegistry built with your AuthStorage: new ModelRegistry(authStorage), and omit options.authStorage.
- Or pass only options.authStorage and let the executor create the ModelRegistry.
- If both must be passed, ensure they are the same instance: registry.authStorage === authStorage.
- Audit instance caching — avoid constructing a fresh AuthStorage after the registry was already built.
Example fix
// before
new Executor({ authStorage: myAuth, modelRegistry: new ModelRegistry(discoverAuthStorage()) })
// after
new Executor({ modelRegistry: new ModelRegistry(myAuth) }) Defensive patterns
Strategy: validation
Validate before calling
function assertConsistentAuth(opts: { authStorage?: AuthStorage; modelRegistry?: ModelRegistry }): void {
if (opts.authStorage && opts.modelRegistry && opts.modelRegistry.authStorage !== opts.authStorage) {
throw new Error("authStorage must be modelRegistry.authStorage when both are passed");
}
} Try / catch
try {
const executor = new Executor(options);
} catch (err) {
if (String(err.message).includes("must be the same instance")) {
// rebuild with a single source of truth
return new Executor({ modelRegistry: new ModelRegistry(options.authStorage) });
}
throw err;
} Prevention
- Adopt one DI pattern: always construct ModelRegistry from your AuthStorage and pass only the registry.
- Memoize the AuthStorage instance per profile directory so all consumers share it.
- Never construct a second AuthStorage after the registry exists.
When it happens
Trigger: Creating the task executor with options = { authStorage: instanceA, modelRegistry: registryB } where registryB.authStorage !== instanceA — the mismatch check `options.authStorage && options.authStorage !== authStorage` fires.
Common situations: Embedding the SDK and constructing a ModelRegistry with its own discovered auth storage while separately passing a custom AuthStorage, wiring two different profile directories, or caching instances across config reloads so one became stale.
Related errors
- gitlab-duo-agent
- No API key for ${resolved.model.provider}/${resolved.model.i
- No available model to generate agent specification.
- options.authStorage and options.modelRegistry.authStorage mu
- Security scans require a stored OAuth account for ${provider
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/feb14ea20b2b877f.
Report an issue: GitHub.