Skip to content

[Bug]: Open WebUI-backed UUID chats can split into separate <uuid> and agent:main:<uuid> session records #49202

Description

@SHAREN

Bug type
Behavior bug (incorrect output/state without crash)

Summary
Open WebUI-backed chats that use an opaque bare UUID as the session key can split into two separate OpenClaw session records:

  • <uuid>
  • agent:main:<uuid>

When that happens, one logical chat diverges between Open WebUI and OpenClaw Control UI.

Steps to reproduce

  1. Configure Open WebUI on top of OpenClaw so that a WebUI chat uses a stable bare UUID as its chat/session identity.
  2. Start a new chat in Open WebUI.
  3. Open the same chat in OpenClaw Control UI using that UUID.
  4. Send a message from Control UI.
  5. Inspect the session index and transcript files.

Short practical repro that we observed:

  1. Create a chat in Open WebUI.
  2. Open the same UUID in OpenClaw Control UI (/chat?session=<uuid>).
  3. Send a message from Control UI.
  4. After that:
    • history can diverge between the two UIs
    • the original Open WebUI chat may no longer reflect the same thread
    • sessions.json can end up containing both <uuid> and agent:main:<uuid> as separate records

Expected behavior
For an Open WebUI-backed chat that already exists under a bare UUID, OpenClaw should preserve that UUID as the canonical session identity.

Control UI and Open WebUI should read/write the same session entity, and sessions.json should not create a second record under agent:main:<uuid>.

Actual behavior
One logical chat can become two separate OpenClaw session records:

  • <uuid>
  • agent:main:<uuid>

This is not just an alias/display issue. In the broken case, the two entries have different:

  • sessionId
  • sessionFile

That means the system is actually storing one logical chat as two backend sessions.

OpenClaw version
2026.3.13

Operating system
Ubuntu server

Install method
Self-hosted OpenClaw gateway with Open WebUI via Docker

Model
openai-codex/gpt-5.4

Provider / routing chain
Open WebUI -> local OpenAI-compatible proxy -> OpenClaw gateway -> openai-codex/gpt-5.4

Config file / key location
Relevant places:

  • ~/.openclaw/agents/main/sessions/sessions.json
  • ~/.openclaw/agents/main/sessions/<sessionId>.jsonl
  • src/gateway/session-utils.ts
  • src/gateway/server-methods/chat.ts
  • ui/src/ui/app-settings.ts

Additional provider/model setup details
Open WebUI was connected to OpenClaw through a local OpenAI-compatible proxy with stable chat/session IDs preserved across requests.

This does not appear to be a model/provider bug. It looks like a backend session canonicalization bug inside OpenClaw.

Logs, screenshots, and evidence
Key evidence: sessions.json contained two different records for the same logical chat:

  • <uuid>
  • agent:main:<uuid>

And these were not two names for the same object. They pointed to different:

  • sessionId
  • sessionFile

Example shape of the broken state:

  • short key record:
    • sessionId: <id-a>
    • sessionFile: <id-a>.jsonl
  • canonical key record:
    • sessionId: <id-b>
    • sessionFile: <id-b>.jsonl

That shows the problem had already crossed from "wrong key display" into actual duplicated session storage.

Additional clue: the UI already contains a special workaround in ui/src/ui/app-settings.ts:

  • normalizeChatUrlSessionKey(...)
  • it rewrites agent:main:<uuid> back to <uuid> for opaque UUID chats

That strongly suggests the frontend already knows these WebUI-backed UUID chats are special, while the backend still canonicalizes them too aggressively.

Impact and severity
Affected:

  • self-hosted OpenClaw users who integrate Open WebUI and also access the same chats from OpenClaw Control UI

Severity:

  • High

Frequency:

  • Reproducible for affected Open WebUI-backed chats

Consequence:

  • one logical chat can split into two backend sessions
  • history diverges between UIs
  • some messages are written into a different transcript file
  • already-broken chats require manual cleanup/repair
  • operators cannot reliably use Open WebUI and Control UI as two views of the same conversation

Additional information
We traced the likely root cause and validated a local fix.

Root cause:

  • in src/gateway/session-utils.ts, a bare UUID such as <uuid> was treated like a generic session key and canonicalized into agent:main:<uuid>
  • for Open WebUI-backed opaque UUID chats, that is incorrect because the bare UUID is already the real session identity
  • chat.send in src/gateway/server-methods/chat.ts then uses the canonicalized key, which allows Control UI writes to target a second backend entity instead of the original short-key session

Proposed fix
Apply a narrow backend fix:

  1. In src/gateway/session-utils.ts, if the session key is a bare opaque UUID used by WebUI-backed chats, preserve it as-is.
  2. Do not rewrite <uuid> into agent:main:<uuid> for that special case.
  3. Apply the same rule consistently to related session resolution / combined-store canonicalization paths.
  4. Keep this rule narrow and do not apply it to normal structured keys such as:
    • agent:main:telegram:...
    • agent:main:discord:...
    • other standard agent session keys

Files involved in the fix

  • src/gateway/session-utils.ts
  • src/gateway/server-methods/chat.ts
  • reference/hint from existing UI workaround:
    • ui/src/ui/app-settings.ts

Local verification
We validated a local fix that preserves bare UUID keys for WebUI-backed chats:

  • new split sessions stopped being created
  • bare UUIDs were no longer rewritten into agent:main:<uuid> for these chats
  • relevant gateway tests passed locally

Important note:

  • this fix prevents new split cases
  • it does not automatically merge already-broken historical session records

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions