openclaw - 💡(How to fix) Fix [Bug]: ACP thread-bound Discord sessions can lose deliveryContext.threadId, causing completion to route to wrong surface [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#56143Fetched 2026-04-08 01:44:25
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

Discord-launched ACP sessions created as thread-bound/persistent sessions do not always complete back into the expected Discord thread. In the failing case, the ACP session metadata kept only {"channel":"discord"} in deliveryContext, and the completion surfaced to Telegram instead of the Discord thread. In the successful case, deliveryContext included both to and threadId, and completion landed in the correct Discord thread.

Current local workaround: for one-shot ACP work launched from chat, use mode="run" plus streamTo="parent" instead of a thread-bound ACP session.

Root Cause

  • completion visibility becomes nondeterministic for ACP thread sessions
  • Sergio may miss the result because it lands on the wrong surface
  • local orchestration guidance has to treat ACP one-shot work differently from true HITL ACP threads

Fix Action

Fix / Workaround

Current local workaround: for one-shot ACP work launched from chat, use mode="run" plus streamTo="parent" instead of a thread-bound ACP session.

Current Workaround

Smoke Test Evidence For Workaround

Code Example

"agent:codex:acp:e180fe5f-a184-4d16-a1ff-43cde5be10c8": {
  "spawnedBy": "agent:main:discord:channel:1478094238309941418",
  "label": "Memory/Vault Cleanup — Phase 2",
  "deliveryContext": {
    "channel": "discord"
  },
  "groupId": "1478094238309941418",
  "groupChannel": "#openclaw-dev",
  "status": "done"
}

---

"agent:codex:acp:f5a11900-bfa5-4ccf-a61c-71537285f4ab": {
  "spawnedBy": "agent:main:discord:channel:1478094238309941418",
  "label": "Memory/Vault Cleanup — Implementation v2",
  "deliveryContext": {
    "channel": "discord",
    "to": "channel:1487262972073087018",
    "accountId": "default",
    "threadId": "1487262972073087018"
  },
  "origin": {
    "provider": "discord",
    "to": "channel:1487262972073087018",
    "threadId": "1487262972073087018"
  },
  "status": "done"
}

---

- agent:codex:acp:e180fe5f-a184-4d16-a1ff-43cde5be10c8
- deliveryContext: {"channel":"discord"}
+ agent:codex:acp:f5a11900-bfa5-4ccf-a61c-71537285f4ab
+ deliveryContext: {"channel":"discord","to":"channel:1487262972073087018","threadId":"1487262972073087018"}

---

sessions_spawn(
  task="...",
  runtime="acp",
  agentId="codex",  # or claude
  mode="run",
  streamTo="parent"
)

---

{
  "runId": "cc214bec-d565-4791-a5bd-f95eb5433da1",
  "parentSessionKey": "agent:main:discord:channel:1478094238309941418",
  "childSessionKey": "agent:codex:acp:cffb62e7-0d1b-4a2e-b3ec-46d0cf23cf1f",
  "kind": "system_event",
  "text": "Started codex session agent:codex:acp:cffb62e7-0d1b-4a2e-b3ec-46d0cf23cf1f. Streaming progress updates to parent session."
}
RAW_BUFFERClick to expand / collapse

Title

ACP thread-bound Discord sessions can lose thread-bound completion routing when deliveryContext.threadId is absent

Summary

Discord-launched ACP sessions created as thread-bound/persistent sessions do not always complete back into the expected Discord thread. In the failing case, the ACP session metadata kept only {"channel":"discord"} in deliveryContext, and the completion surfaced to Telegram instead of the Discord thread. In the successful case, deliveryContext included both to and threadId, and completion landed in the correct Discord thread.

Current local workaround: for one-shot ACP work launched from chat, use mode="run" plus streamTo="parent" instead of a thread-bound ACP session.

Expected Behavior

If an ACP session is launched from a Discord thread-bound context, its completion should route back to that same Discord thread, or at minimum to the same Discord surface that initiated it.

Actual Behavior

A thread-bound ACP session can finish without a thread-aware deliveryContext. When that happens, completion routing is inconsistent and may land on another surface instead of the originating Discord thread.

Exact Reproduction Steps

  1. From a Discord chat, spawn an ACP session intended to behave as a thread-bound/persistent session.
  2. Let the ACP worker finish normally.
  3. Inspect the resulting ACP session metadata in /home/sergio/.openclaw/agents/codex/sessions/sessions.json.
  4. Compare a failed ACP session whose deliveryContext lacks threadId with a successful ACP session whose deliveryContext includes threadId.
  5. Observe that the failed session completion was delivered to Telegram, while the successful one completed in the Discord thread.

Evidence

Failed session

  • Session key: agent:codex:acp:e180fe5f-a184-4d16-a1ff-43cde5be10c8
  • Label: Memory/Vault Cleanup — Phase 2
  • Result: completion went to Telegram
  • Metadata snippet from /home/sergio/.openclaw/agents/codex/sessions/sessions.json:
"agent:codex:acp:e180fe5f-a184-4d16-a1ff-43cde5be10c8": {
  "spawnedBy": "agent:main:discord:channel:1478094238309941418",
  "label": "Memory/Vault Cleanup — Phase 2",
  "deliveryContext": {
    "channel": "discord"
  },
  "groupId": "1478094238309941418",
  "groupChannel": "#openclaw-dev",
  "status": "done"
}

Successful session

  • Session key: agent:codex:acp:f5a11900-bfa5-4ccf-a61c-71537285f4ab
  • Label: Memory/Vault Cleanup — Implementation v2
  • Result: completion landed in the Discord thread
  • Metadata snippet from /home/sergio/.openclaw/agents/codex/sessions/sessions.json:
"agent:codex:acp:f5a11900-bfa5-4ccf-a61c-71537285f4ab": {
  "spawnedBy": "agent:main:discord:channel:1478094238309941418",
  "label": "Memory/Vault Cleanup — Implementation v2",
  "deliveryContext": {
    "channel": "discord",
    "to": "channel:1487262972073087018",
    "accountId": "default",
    "threadId": "1487262972073087018"
  },
  "origin": {
    "provider": "discord",
    "to": "channel:1487262972073087018",
    "threadId": "1487262972073087018"
  },
  "status": "done"
}

Metadata diff

- agent:codex:acp:e180fe5f-a184-4d16-a1ff-43cde5be10c8
- deliveryContext: {"channel":"discord"}
+ agent:codex:acp:f5a11900-bfa5-4ccf-a61c-71537285f4ab
+ deliveryContext: {"channel":"discord","to":"channel:1487262972073087018","threadId":"1487262972073087018"}

The meaningful difference is the missing to and threadId in the failed ACP session.

Suspected Root Cause

ACP sessions appear not to benefit from Discord's subagent delivery target hook rewriting in the same way standard sub-agents do. As a result, a thread-bound ACP session can be created without the final, thread-specific deliveryContext fields (to, threadId) that completion routing needs.

Put differently: the ACP runtime session exists and runs, but the delivery metadata rewrite that pins completions to the Discord thread is not reliably applied.

Current Workaround

For one-shot ACP work launched from chat, use:

sessions_spawn(
  task="...",
  runtime="acp",
  agentId="codex",  # or claude
  mode="run",
  streamTo="parent"
)

This avoids relying on thread-bound ACP completion routing and has been locally verified as working.

Smoke Test Evidence For Workaround

  • Verified pattern: mode="run" + streamTo="parent"
  • Smoke test run ID: cc214bec-d565-4791-a5bd-f95eb5433da1
  • Local evidence file: /home/sergio/.openclaw/agents/codex/sessions/e5f02c40-3fea-4e57-b390-fac9900e0374.acp-stream.jsonl

Relevant event:

{
  "runId": "cc214bec-d565-4791-a5bd-f95eb5433da1",
  "parentSessionKey": "agent:main:discord:channel:1478094238309941418",
  "childSessionKey": "agent:codex:acp:cffb62e7-0d1b-4a2e-b3ec-46d0cf23cf1f",
  "kind": "system_event",
  "text": "Started codex session agent:codex:acp:cffb62e7-0d1b-4a2e-b3ec-46d0cf23cf1f. Streaming progress updates to parent session."
}

The corresponding session metadata for the smoke test shows an ACP one-shot session labeled ACP streamTo parent smoke test, which completed successfully without depending on Discord thread delivery metadata.

Why This Matters

  • completion visibility becomes nondeterministic for ACP thread sessions
  • Sergio may miss the result because it lands on the wrong surface
  • local orchestration guidance has to treat ACP one-shot work differently from true HITL ACP threads

Suggested Fix Direction

  • ensure ACP Discord spawns receive the same delivery target rewrite as standard sub-agents before completion routing is finalized
  • or explicitly persist to and threadId into ACP deliveryContext whenever the originating Discord context is thread-bound
  • add a regression test covering Discord thread-bound ACP completion routing

extent analysis

Fix Plan

To fix the issue of ACP thread-bound Discord sessions losing thread-bound completion routing, we need to ensure that the deliveryContext includes to and threadId for thread-bound sessions. Here are the steps:

  • Modify the ACP session creation logic to include to and threadId in the deliveryContext when the session is created from a thread-bound Discord context.
  • Update the completion routing logic to use the to and threadId from the deliveryContext to route the completion to the correct Discord thread.

Example code:

def create_acp_session(task, runtime, agent_id, mode, stream_to, discord_context):
    # ...
    delivery_context = {
        "channel": "discord",
    }
    if discord_context and discord_context.get("thread_id"):
        delivery_context["to"] = f"channel:{discord_context['thread_id']}"
        delivery_context["threadId"] = discord_context["thread_id"]
    # ...
    return sessions_spawn(
        task=task,
        runtime=runtime,
        agentId=agent_id,
        mode=mode,
        streamTo=stream_to,
        deliveryContext=delivery_context,
    )

Verification

To verify the fix, create a new ACP session from a thread-bound Discord context and check that the deliveryContext includes to and threadId. Then, complete the session and verify that the completion is routed to the correct Discord thread.

Extra Tips

  • Add a regression test to cover Discord thread-bound ACP completion routing to ensure that the fix does not introduce new issues.
  • Consider adding logging to track the deliveryContext and completion routing for ACP sessions to help diagnose any future issues.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Bug]: ACP thread-bound Discord sessions can lose deliveryContext.threadId, causing completion to route to wrong surface [1 participants]