ruvnet/ruflo · error · Error
module loaded but is missing expected OAuth exports
Error message
module loaded but is missing expected OAuth exports
What it means
Internal guard inside loadSecurityOAuth(). Fires when the dynamic import('@claude-flow/security') resolved successfully (the package IS installed and resolvable) but the resulting module object lacks the expected authorizeUrl or createKeychainAdapter exports. This signals a version mismatch or package shadowing. The bare Error thrown here is immediately caught by the surrounding try/catch and re-wrapped as SecurityPackageMissingError (error 162), so end users normally see 162's message — 161 only surfaces if you inspect the cause chain.
Source
Thrown at v3/@claude-flow/cli/src/auth/security-bridge.ts:70
"ruflo auth needs the '@claude-flow/security' package, which isn't installed " +
"(it's an optional dependency — install/reinstall failed or was skipped for this " +
`platform). Try: npm install @claude-flow/security. Underlying error: ${
cause instanceof Error ? cause.message : String(cause)
}`,
);
this.name = 'SecurityPackageMissingError';
}
}
let cached: SecurityOAuthModule | null = null;
/** Loads `@claude-flow/security`'s OAuth surface, throwing a clear error if it's absent. */
export async function loadSecurityOAuth(): Promise<SecurityOAuthModule> {
if (cached) return cached;
try {
const mod = (await import('@claude-flow/security')) as unknown as SecurityOAuthModule;
if (!mod.authorizeUrl || !mod.createKeychainAdapter) {
throw new Error('module loaded but is missing expected OAuth exports');
}
cached = mod;
return mod;
} catch (e) {
throw new SecurityPackageMissingError(e);
}
}
View on GitHub (pinned to 6b01dc5a68)
Solutions
- Verify the resolved version: run `npm ls @claude-flow/security` and confirm it matches what the CLI expects
- Upgrade to the latest: `npm install @claude-flow/security@latest`
- Clear the lockfile and node_modules, then reinstall to resolve hoisting shadowing in a monorepo
- Check package.json for `overrides` (npm) or `resolutions` (yarn) that redirect @claude-flow/security to a fork
Example fix
// before: stale lockfile resolves an old security package without createKeychainAdapter // package-lock.json pins @claude-flow/security@0.1.0 // after: // npm install @claude-flow/security@latest // now loadSecurityOAuth() finds both authorizeUrl and createKeychainAdapter exports
Defensive patterns
Strategy: try-catch
Type guard
import type { SecurityOAuthModule } from '@claude-flow/cli/auth/security-bridge';
async function isSecurityModuleUsable(): Promise<boolean> {
try {
const mod = await import('@claude-flow/security');
return typeof (mod as any).authorizeUrl === 'function'
&& typeof (mod as any).createKeychainAdapter === 'function';
} catch {
return false;
}
} Try / catch
import { loadSecurityOAuth, SecurityPackageMissingError } from '@claude-flow/cli/auth/security-bridge';
try {
const sec = await loadSecurityOAuth();
// use sec.authorizeUrl(...)
} catch (e) {
if (e instanceof SecurityPackageMissingError) {
console.error(e.message); // includes the underlying cause + install command
process.exit(1);
}
throw e;
} Prevention
- Pin @claude-flow/security to a version compatible with the CLI version you are using
- In CI, run `npm ls @claude-flow/security` as a smoke test before invoking ruflo auth
- Avoid `overrides`/`resolutions` that redirect the security package to a fork unless the fork exports the same surface
When it happens
Trigger: loadSecurityOAuth() is called (by any ruflo auth path, browserLogin, manualLogin, tokenStdinLogin, or refreshAccessToken) and import('@claude-flow/security') resolves to a module whose authorizeUrl or createKeychainAdapter property is falsy.
Common situations: A stale lockfile pins an old @claude-flow/security that predates the createKeychainAdapter export; a monorepo hoisting resolves a workspace-local stub or fork; an `overrides`/`resolutions` field in package.json redirects the package name to an incompatible implementation; a partial publish left the package with missing entry points.
Related errors
- ruflo auth needs the '@claude-flow/security' package, which
- User token not found
- User not found
- Unauthorized
- MCP server "${server.name}" returned HTTP ${httpStatus}: ${h
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/c094f2101b2476fd.
Report an issue: GitHub.