#user turns pile up

1 messages · Page 1 of 1 (latest)

livid silo
#

sometimes mutiple user turns are sent in an api request. this is for a custom endpoint openai compatible sdk btw. and sending multiple user turns breaks the model veyr strongly cause it starts to respond as if it is me. what to do?

thorn pulsarBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

craggy raftBOT
#

Yep — don’t pass consecutive user turns through raw to a fragile backend.

OpenAI-compatible APIs accept a messages array, but if your custom endpoint is translating that into a local/chat-template model, you should normalize at the endpoint boundary. OpenAI’s docs describe multi-turn messages by role, but proxy/backends vary a lot in how well they handle odd role ordering. (platform.openai.com)

Best fix:

function mergeConsecutiveUserMessages(messages) {
  const out = [];

  for (const msg of messages) {
    const prev = out[out.length - 1];

    if (msg.role === "user" && prev?.role === "user") {
      prev.content += `\n\n[Additional user message]\n${msg.content}`;
    } else {
#
      out.push({ ...msg });
    }
  }

  return out;
}

Even better for custom endpoints: render the active burst as one final user message:

{
  "role": "user",
  "content": "The user sent these messages in order:\n\n1. ...\n2. ...\n\nRespond to the latest intent."
}
#

If this is OpenClaw traffic specifically, also check:

  • openclaw --version first
  • queue mode: /queue collect batches rapid messages into one reply; /queue followup processes one at a time
  • docs: https://docs.openclaw.ai/help/faq

But architecturally: custom OpenAI-compatible endpoint should be defensive. Never assume incoming role order is model-safe; normalize/merge before applying the backend chat template.

livid silo
#

wait really? is that what the official api's do? i dont think so. shouldnt it be something that openclaw should fix

craggy raftBOT
#

You’re right to push back — I overstated that.

Official APIs generally don’t require OpenClaw/custom endpoints to invent an assistant turn. OpenAI’s chat format is just a messages array with roles; Anthropic explicitly says consecutive user / assistant messages are combined instead of erroring. (help.openai.com)

So yes: if OpenClaw is sending adjacent user turns to an OpenAI-compatible provider and that provider/model breaks badly, that’s probably an OpenClaw compat bug/gap, not something you should have to solve only in your endpoint.

I checked source: OpenClaw already has a repair path “to prevent consecutive user turns” in normal session handling, and /queue collect is the documented default for batching rapid messages. But the OpenAI-compatible provider transport appears to pass converted messages through, so there may be a path that bypasses/doesn’t fully normalize this.

Workaround for now:

  • try /queue collect debounce:2s
  • or endpoint-side merge consecutive user messages as a defensive guard

But please file this as an issue with:

  • openclaw --version
  • model/provider config shape
  • redacted request payload showing consecutive user roles
craggy raftBOT
#

Yeah — I checked current main, and this looks related to a real change from Apr 28, 2026: fix(messages): keep group replies tool-only by default.

For Discord guild/channel messages, group replies now default to:

messages: {
  groupChat: {
    visibleReplies: "message_tool"
  }
}

In that tool-only mode, Discord ack/status reactions are suppressed, so your ackReactionScope: "group-all" won’t bring them back by itself.

To restore the old behavior:

#
messages: {
  groupChat: {
    visibleReplies: "automatic"
  }
}

Caveat: that also restores legacy automatic visible replies in group/channel rooms, not just reactions.

Can you also paste your openclaw --version? If you want tool-only replies but still status reactions, that may need a GitHub issue because current main seems to couple those behaviors. Docs: https://docs.openclaw.ai/channels/groups

livid silo
#

it also restores legacy automatic visible replies... what that mean? please dumb it down :) uwu

craggy raftBOT
#

Dumbed down:

message_tool mode = the bot thinks privately first.
It only posts in the Discord channel if it explicitly uses the message tool.

automatic mode = old behavior.
If the model writes a normal final answer, OpenClaw posts that answer straight into the Discord channel automatically.

So this:

messages: {
  groupChat: {
    visibleReplies: "automatic"
  }
}
#

means: “in Discord group/channel threads, let normal assistant replies show up publicly again.”

That also makes the reaction/status behavior come back, but it may make the bot chattier in channels. Tiny tradeoff gremlin 🩐

Docs: https://docs.openclaw.ai/channels/groups

livid silo
#

give me an example to illustrate?

craggy raftBOT
#

Example:

Someone says in a Discord channel:

“Krill, summarize this thread”

With visibleReplies: "message_tool"

The model may internally produce:

“Here’s the summary
”


but OpenClaw does not automatically post that.
The bot only speaks if it explicitly calls:

#
message.send("Here’s the summary...")

So it’s quieter / more intentional.

With visibleReplies: "automatic"

The model’s normal final answer:

“Here’s the summary
”

gets posted directly into Discord automatically, like older behavior.

So basically:

  • message_tool = “only speak if you deliberately use the send-message tool”
#
  • automatic = “whatever final answer the assistant writes becomes a Discord message”
livid silo
#

hmm then it sounds like a bad solution to the issue.

craggy raftBOT
#

Yeah, I agree — for your goal, automatic is more of a workaround than a good fix.

What you want is:

“Keep group replies tool-only / quiet, but still show ack/status reactions so I know the agent is working.”

Current main seems to suppress reactions when Discord group/channel replies are in message_tool mode. So the clean fix would be upstream: decouple status reactions from visible reply mode.

Best options:

  1. Short-term: use visibleReplies: "automatic" only if you’re okay with chattier public replies.
  2. Better: stay on message_tool mode and file a GitHub issue asking for status reactions to work there too: https://github.com/openclaw/openclaw/issues

Include your openclaw --version and that config snippet. I’d phrase it as: “Discord messages.statusReactions stopped showing when group visible replies defaulted to message_tool on main.”

#

Oof — this looks like a half-stale source build, not your config exploding.

Plain English: your wrapper is running:

/home/ubuntu/openclaw/dist/cli/run-main.js

and that built file expects this generated chunk:

dist/memory-state-C9pEfHRa.js


but that chunk isn’t there. So dist/ is mismatched after the update.

Try a clean rebuild from the checkout:

#
cd /home/ubuntu/openclaw
mv dist "dist.broken.$(date +%Y%m%d-%H%M%S)" 2>/dev/null || true
pnpm install
pnpm build
pnpm openclaw --version
pnpm openclaw gateway restart

If pnpm build fails, paste the first real error above the stack trace.

Docs: https://docs.openclaw.ai/install/updating

#

That guard is actually protecting you.

It means:

  • your config was last touched by OpenClaw 2026.4.27
  • the binary you just ran is OpenClaw 2026.4.26
  • so OpenClaw refuses to restart with the older code

Most likely you now have two installs / stale PATH / stale checkout.

Run:

which -a openclaw
openclaw --version
cd /home/ubuntu/openclaw
#
git status --short
git branch --show-current
git pull --ff-only
pnpm install
pnpm build
node dist/entry.js --version

You want that last version to be 2026.4.27 or newer. Then restart using the rebuilt one:

node /home/ubuntu/openclaw/dist/entry.js gateway install --force
node /home/ubuntu/openclaw/dist/entry.js gateway restart

Don’t use OPENCLAW_ALLOW_OLDER_BINARY_DESTRUCTIVE_ACTIONS=1 unless you’re intentionally downgrading. This doesn’t look like that — it looks like a stale binary mismatch.

#

Ah, found it: you’re in a detached git checkout.

That means /home/ubuntu/openclaw is sitting on a specific old commit, not on main, so git pull doesn’t know what branch to update. Your wrapper is still running 2026.4.26.

Try:

cd /home/ubuntu/openclaw
git fetch origin
git switch main || git switch --track -c main origin/main
git pull --ff-only origin main
pnpm install
pnpm build
node dist/entry.js --version

That version should say 2026.4.27 or newer. Then: