{"record":{"id":"4fd77522048f86ee","repo":"musistudio/claude-code-router","slug":"no-bot-gateway-conversationref-is-configured-and-n","errorCode":null,"errorMessage":"No Bot Gateway conversationRef is configured and no inbound bot event context is available.","messagePattern":"No Bot Gateway conversationRef is configured and no inbound bot event context is available\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/codex/cli-middleware-runtime.ts","lineNumber":5485,"sourceCode":"\n  forwardDecision() {\n    if (this.config.forwardAllAgentMessages) {\n      return { shouldForward: true, reason: \"forward_all\" };\n    }\n    if (!this.config.handoff.enabled) {\n      return { shouldForward: false, reason: \"forwarding_disabled\" };\n    }\n    const presence = evaluateHandoffPresence(this.config.handoff);\n    return {\n      shouldForward: presence.away,\n      reason: presence.away ? presence.reasons.join(\", \") : presence.evidence.join(\", \")\n    };\n  }\n\n  async sendText(key, text, params, decision) {\n    const conversationRef = this.resolveConversationRef();\n    if (!conversationRef) {\n      throw new Error(\"No Bot Gateway conversationRef is configured and no inbound bot event context is available.\");\n    }\n    const outbound = {\n      tenantId: this.resolveTenantId(),\n      integrationId: this.resolveIntegrationId(),\n      conversationRef,\n      intent: {\n        type: \"text\",\n        text\n      },\n      idempotencyKey: \"ccr:handoff:\" + this.config.profileId + \":\" + stableBotKey(key)\n    };\n    await this.sendDurable(outbound, { kind: \"handoff\", sourceKey: key });\n    this.rememberForwarded(key);\n    log(\"bot_gateway_forward_sent\", {\n      key,\n      reason: decision.reason,\n      textLen: text.length,\n      threadId: params.threadId || \"\",","sourceCodeStart":5467,"sourceCodeEnd":5503,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/agents/codex/cli-middleware-runtime.ts#L5467-L5503","documentation":"sendText() needs a conversation reference to address an outbound Bot Gateway message. It first tries runtime-resolved context (inbound event) and falls back to configured conversationRef; when both are absent it cannot know where to deliver and throws. The Gateway requires an explicit destination for proactive (non-reply) sends.","triggerScenarios":"Calling sendText() outside an inbound bot event flow while the Bot Gateway config has no conversationRef set — e.g. proactive/scheduled messages, background notifications, or a code path that lost the event context.","commonSituations":"Configuring a bot integration without a default conversationRef and then sending proactive messages; refactoring moved the call outside the event handler; config file missing the gateway section after an upgrade changed its schema.","solutions":["Set conversationRef in the Bot Gateway config so proactive sends have a default destination","If replying to a user, use sendReplyToEvent(event, ...) instead, which derives the ref from the event","Only call sendText() within an inbound event context when no configured ref exists","Validate config on startup and fail fast with a clear message when proactive sending is enabled without conversationRef"],"exampleFix":"// before\nawait gateway.sendText(key, text, params); // throws: no conversationRef\n\n// after\nconst conversationRef = gateway.resolveConversationRef();\nif (conversationRef) {\n  await gateway.sendText(key, text, params);\n} else {\n  await gateway.sendReplyToEvent(event, text, key); // reply path derives ref from event\n}","handlingStrategy":"validation","validationCode":"const ref = gateway.resolveConversationRef(); if (!ref) throw new ConfigError(\"set botGateway.conversationRef before proactive sends\");","typeGuard":"function canSendProactively(gateway) { return Boolean(gateway.resolveConversationRef() || gateway.config.conversationRef); }","tryCatchPattern":"try { await gateway.sendText(key, text, params); } catch (e) { if (/no conversationRef is configured/i.test(String(e))) { /* fall back to event-reply path or alert config */ } else throw e; }","preventionTips":["Always configure conversationRef if proactive bot messages are possible","Prefer event-reply APIs inside inbound event handlers","Fail fast at startup when proactive sending is enabled without a configured ref"],"tags":["bot-gateway","conversation-ref","config","proactive-message"],"backgroundTag":"missing-destination-address","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}