{"record":{"id":"d2a6fc2992420c0b","repo":"ruvnet/ruflo","slug":"ruflo-auth-needs-the-claude-flow-security-packa","errorCode":null,"errorMessage":"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)}","messagePattern":"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: (.+?)","errorType":"exception","errorClass":"SecurityPackageMissingError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/auth/security-bridge.ts","lineNumber":75,"sourceCode":"    );\n    this.name = 'SecurityPackageMissingError';\n  }\n}\n\nlet cached: SecurityOAuthModule | null = null;\n\n/** Loads `@claude-flow/security`'s OAuth surface, throwing a clear error if it's absent. */\nexport async function loadSecurityOAuth(): Promise<SecurityOAuthModule> {\n  if (cached) return cached;\n  try {\n    const mod = (await import('@claude-flow/security')) as unknown as SecurityOAuthModule;\n    if (!mod.authorizeUrl || !mod.createKeychainAdapter) {\n      throw new Error('module loaded but is missing expected OAuth exports');\n    }\n    cached = mod;\n    return mod;\n  } catch (e) {\n    throw new SecurityPackageMissingError(e);\n  }\n}\n","sourceCodeStart":57,"sourceCodeEnd":78,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/auth/security-bridge.ts#L57-L78","documentation":"SecurityPackageMissingError is the user-facing error thrown by loadSecurityOAuth() when it cannot produce a usable @claude-flow/security module for ANY reason — whether the package is absent (ERR_MODULE_NOT_FOUND) or loaded but malformed (error 161, which is caught and rewrapped here). Per ADR-306, @claude-flow/security is an optionalDependency because ruflo auth is the only capability that genuinely requires it; local/offline ruflo commands work without it. The error message embeds the underlying cause and gives the install command.","triggerScenarios":"Any ruflo auth subcommand (login, status with refresh, token-stdin) or any code path calling loadSecurityOAuth() when @claude-flow/security is not resolvable from the CLI package's node_modules, OR when the inner export-check (error 161) fires and is caught.","commonSituations":"Install was run with --omit=optional or --no-optional; a Docker/CI image built with npm ci --omit=optional; the security package's platform-specific native dependency failed to build so npm skipped it; npm prune removed it; a monorepo did not hoist the optional dep to the CLI package's depth.","solutions":["Run `npm install @claude-flow/security` in the package where @claude-flow/cli is installed","If install used --omit=optional, re-run without that flag or add @claude-flow/security to direct `dependencies` so it is never skipped","For Docker/CI, change the install line to not skip optional dependencies, or explicitly add the package to dependencies","Verify platform support — check the security package's `os` and `cpu` fields in its package.json if install silently skips for your platform"],"exampleFix":"// before: optional dependency skipped\n// Dockerfile: RUN npm ci --omit=optional\n\n// after:\n// Dockerfile: RUN npm ci\n// or add to package.json dependencies:\n//   \"@claude-flow/security\": \"^latest\"","handlingStrategy":"try-catch","validationCode":"// Check at startup whether the optional security package is resolvable\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nconst require = createRequire(import.meta.url);\nfunction isSecurityPackageInstalled(): boolean {\n  try {\n    require.resolve('@claude-flow/security');\n    return true;\n  } catch {\n    return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"import { loadSecurityOAuth, SecurityPackageMissingError } from '@claude-flow/cli/auth/security-bridge';\n\ntry {\n  await loadSecurityOAuth();\n} catch (e) {\n  if (e instanceof SecurityPackageMissingError) {\n    // User-facing message already includes the install command.\n    // For local-only commands, you can degrade gracefully; for auth commands,\n    // print the message and exit.\n    console.error(e.message);\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Do not install with --omit=optional in environments that need ruflo auth","Add @claude-flow/security to direct dependencies if your workflow always needs auth, so it is never treated as optional","In Dockerfiles, run `npm ci` without --omit=optional, or explicitly install the package afterward"],"tags":["auth","dependencies","optional-deps","install","security-package"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}