{"record":{"id":"c6bd8c87e6480039","repo":"ruvnet/ruflo","slug":"aidefencegate-not-attached-call-attachguidance","errorCode":null,"errorMessage":"AIDefenceGate not attached. Call attachGuidance({ aiDefenceGate }) first.","messagePattern":"AIDefenceGate not attached\\. Call attachGuidance\\((.+?)\\) first\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/guidance/src/ruvbot-integration.ts","lineNumber":716,"sourceCode":"   */\n  disconnect(): void {\n    if (!this.ruvbot) return;\n\n    for (const [event, handler] of this.boundHandlers) {\n      this.ruvbot.off(event, handler);\n    }\n\n    this.boundHandlers.clear();\n    this.ruvbot = null;\n  }\n\n  /**\n   * Evaluate a ruvbot AIDefence result and return a GateResult-compatible\n   * decision. Can be called independently of event wiring.\n   */\n  async evaluateAIDefence(input: string): Promise<GateResult> {\n    if (!this.aiDefenceGate) {\n      throw new Error(\n        'AIDefenceGate not attached. Call attachGuidance({ aiDefenceGate }) first.',\n      );\n    }\n\n    const result = await this.aiDefenceGate.evaluateInput(input);\n    return this.aiDefenceGate.toGateResult(result, 'manual-evaluation');\n  }\n\n  /**\n   * Get the proof chain for a specific session.\n   */\n  getSessionProofChain(sessionId: string): import('./proof.js').ProofChain | undefined {\n    return this.sessionChains.get(sessionId);\n  }\n\n  /**\n   * Get all active session IDs.\n   */","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/guidance/src/ruvbot-integration.ts#L698-L734","documentation":"Thrown by RuvBotGuidanceBridge.evaluateAIDefence(input) when no AIDefenceGate has been provided via attachGuidance({ aiDefenceGate }). The bridge wires ruvbot events independently of guidance attachment, so a manual defence evaluation explicitly verifies the gate exists before delegating to evaluateInput() and toGateResult(). It indicates incomplete bridge setup.","triggerScenarios":"Creating a RuvBotGuidanceBridge around a ruvbot instance (optionally with event wiring) and calling await bridge.evaluateAIDefence(text) before calling bridge.attachGuidance({ aiDefenceGate: gate }), or calling attachGuidance with an object that omits aiDefenceGate.","commonSituations":"Using the bridge purely for event translation and adding manual input screening later; setup code where attachGuidance is conditional (only when a gate was configured) but evaluateAIDefence is called unconditionally; partial init during application shutdown/re-initialization where detach() has set the gate reference to null.","solutions":["Call bridge.attachGuidance({ aiDefenceGate: gate }) once during setup, before any evaluateAIDefence() call","If attachGuidance is optional in your flow, guard evaluation behind a check that guidance was attached","After calling detach() (which nulls references), do not reuse the bridge for evaluation — create and re-attach a fresh bridge"],"exampleFix":"// before\nconst bridge = new RuvBotGuidanceBridge(ruvbot, config);\nawait bridge.evaluateAIDefence(userInput); // throws: gate not attached\n\n// after\nconst bridge = new RuvBotGuidanceBridge(ruvbot, config);\nbridge.attachGuidance({ aiDefenceGate });\nawait bridge.evaluateAIDefence(userInput);","handlingStrategy":"validation","validationCode":"// Single setup path: attach guidance before exposing the bridge\nfunction createBridge(ruvbot: RuvBot, gate: AIDefenceGate, config: RuvBotBridgeConfig) {\n  const bridge = new RuvBotGuidanceBridge(ruvbot, config);\n  bridge.attachGuidance({ aiDefenceGate: gate });\n  return bridge;\n}","typeGuard":"// aiDefenceGate is private; track it in your own wrapper\ntype EvaluableBridge = { evaluateAIDefence(i: string): Promise<GateResult> };\nconst evaluatable = new WeakSet<object>();\nfunction isEvaluatable(b: object): b is EvaluableBridge {\n  return evaluatable.has(b);\n}\n// after bridge.attachGuidance({ aiDefenceGate }): evaluatable.add(bridge);","tryCatchPattern":"try {\n  const result = await bridge.evaluateAIDefence(input);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('attachGuidance')) {\n    // configuration gap — fail loudly, do not retry\n    throw new Error('AIDefenceGate missing on bridge; attachGuidance was skipped', { cause: e });\n  }\n  throw e;\n}","preventionTips":["Call attachGuidance in the same function that constructs the bridge","After detach(), mark the bridge as unusable for evaluation instead of reusing it","Cover evaluateAIDefence with an integration test that runs the full setup path"],"tags":["ruvbot","guidance","ai-defence","initialization"],"backgroundTag":"dependency-not-initialized","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}