ruvnet/ruflo · error · SecurityPackageMissingError

ruflo auth needs the '@claude-flow/security' package, which…

Error message

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)}

What it means

SecurityPackageMissingError from loadSecurityOAuth(): the dynamic import('@claude-flow/security') failed outright. The package is an optionalDependency (so core ruflo works without it), but `ruflo auth` cannot — this error converts a raw ERR_MODULE_NOT_FOUND into an actionable install instruction, preserving the underlying cause message.

Solutions

  1. npm install @claude-flow/security (as the message says)
  2. If installs keep skipping it, install without --no-optional/--omit=optional and check npm config get omit
  3. Check the Underlying error text at the end of the message — a build failure in a transitive dep points to toolchain prerequisites
  4. Verify afterwards: node -e "import('@claude-flow/security').then(() => console.log('ok'))"

Example fix

# before
NODE_ENV=production npm ci --omit=optional
ruflo auth login   # SecurityPackageMissingError
# after
npm ci
npm install @claude-flow/security
ruflo auth login
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: fail fast with your own message if the optional dep is absent
try { await import('@claude-flow/security'); }
catch { throw new Error('auth features require @claude-flow/security — run npm install @claude-flow/security'); }

Type guard

import { SecurityPackageMissingError } from '@claude-flow/cli/dist/auth/security-bridge.js';
function isSecurityPackageMissing(e: unknown): e is SecurityPackageMissingError {
  return e instanceof Error && e.name === 'SecurityPackageMissingError';
}

Try / catch

try {
  await runAuthCommand();
} catch (e) {
  if (isSecurityPackageMissing(e)) {
    // e.message already includes the install command and the underlying cause
    console.error(e.message);
    process.exit(5);
  }
  throw e;
}

Prevention

When it happens

Trigger: Any auth flow (browserLogin, device, token-stdin path via loadSecurityOAuth, refresh) when @claude-flow/security is absent from node_modules: install ran with --no-optional / --omit=optional, the platform-specific install step failed or was skipped, or the package was pruned.

Common situations: CI or production images installing with npm ci --omit=optional or NODE_ENV production pruning optionals; yarn/pnpm hoisting quirks dropping optional deps; installing on a platform where a transitive native dependency of the security package fails to build; users who installed a slim/partial tarball.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/d2a6fc2992420c0b. Report an issue: GitHub.

Appendix: source

Thrown at v3/@claude-flow/cli/src/auth/security-bridge.ts:75

    );
    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 fa13ee4ad6)