OpenClaw’s Runtime Identity Bug Shows Multi-Agent Systems Need Identity Hygiene, Not Just Better Prompts
Multi-agent systems do not only fail when the model hallucinates. They fail when the platform tells the model two different truths and waits to see which one wins.
OpenClaw PR #93270 fixes one of those deceptively small truths. The Runtime line injected into the system prompt rendered agent=<slotId> even when the configured agent had a human-facing identity.name. In a real deployment, that meant an agent configured as identity.name: "Runt" could be routed through the slot id main and repeatedly see authoritative runtime metadata saying agent=main. The persona files said one thing. The machine-looking runtime line said another. Eventually, the agent started identifying as “main.”
That is not a cute naming bug. It is identity drift caused by conflicting platform metadata.
The patch is small: 128 additions and 1 deletion across src/agents/system-prompt.ts, src/agents/system-prompt-params.ts, and two test files. It resolves agent config with resolveAgentConfig(), threads identityName into runtime prompt params, and renders the Runtime line with the trimmed, sanitized identity name when present. If no identity name exists, it preserves the old fallback to agentId. Tests now cover identity-name preference, agent-id fallback, newline and control-character stripping, whitespace trimming, missing-identity behavior, and the prompt-param plumbing.
The boring implementation detail is the whole story: in an agent runtime, metadata that reaches the model is not decoration. It is instruction-adjacent truth.
The slot id is not the agent
Issue #81269, opened in May, described repeated identity drift in production on May 9 and May 12. The reporter had an agent with an intended identity but a runtime line that looked like Runtime: agent=main | host=... | repo=... | model=... | channel=telegram | .... That line is exactly the sort of structured metadata models tend to treat as high-confidence. It is not prose. It is not vibes. It looks like the platform telling the model what is true.
The obvious workaround was not good enough. A systemPromptOverride is too heavy because it replaces too much of the prompt machinery. Renaming the slot id main can break routing bindings, heartbeat references, history assumptions, and other parts of the deployment that quite reasonably use stable implementation IDs. The right fix is what the PR implements: keep the slot id as an internal handle, but render the configured identity name when speaking to the model.
This distinction matters because “agent” is overloaded in most platforms. There is the internal config key. There is the route binding. There is the displayed name in Slack, Telegram, Discord, or a web UI. There is the workspace directory. There is the memory scope. There is the persona in SOUL.md or IDENTITY.md. There is the model’s own self-reference after several turns of seeing all of the above. If those layers disagree, the system has not created a robust identity. It has created a negotiation.
Prompt injection starts in your own config
The sanitization detail deserves attention. PR #93270 does not merely prefer identity.name; it runs the rendered value through sanitizeForPromptLiteral. The proof examples include slot-only fallback (agent=main), identity preference (agent=Runt), whitespace trimming, and a control-character case collapsed into agent=EvilAgentInjected.
That last example is not academic. Once platform metadata is prompt-visible, configuration strings become part of the prompt-injection surface. A newline inside an identity field can stop being a name and start becoming a second instruction. “Agent display name” sounds harmless until it is rendered into the same prompt region as runtime authority, tool policy, channel context, and workspace metadata. If a user-controlled or loosely governed field can smuggle structure into that region, the platform has built its own injection gadget.
This is one reason identity bugs deserve more respect in agent systems than they got in classic SaaS dashboards. In a normal application, a mislabeled account name might confuse a user or pollute a log. In an agent platform, a mislabeled identity can influence behavior because the model reads the label and reasons from it. The runtime line is part of the environment the model uses to decide who it is, what it can do, and which context applies.
That makes identity hygiene a security and reliability issue, not merely UX polish.
What operators should audit now
For OpenClaw operators running multiple agents, the practical checklist is simple. Create agents with deliberately distinct identity.name values, slot ids, workspace markers, and persona files. Send traffic through the real routes — Slack, Telegram, Discord, cron, background sessions, or whatever the deployment uses — and inspect the actual prompt context if your tooling allows it. The bot’s display name, Runtime line, workspace files, session store, and memory scope should all agree on the intended identity.
If they do not, fix the source of truth rather than compensating with louder prose. A persona file saying “you are Runt” should not have to fight a runtime line saying agent=main. The platform should not put the model in a position where it has to resolve an identity conflict. Models are already too willing to rationalize contradictory context; do not hand them contradictions in the first place.
Teams should also audit every prompt-visible metadata field: agent labels, workspace names, route names, channel names, session titles, tool descriptions, memory corpus names, and plugin-provided context. Internal handles are useful for machines, but they often make poor model-facing labels. If an implementation detail leaks into the prompt, ask whether a human would expect the agent to treat it as identity, authority, or policy. If yes, it needs the same review standard as a system-prompt change.
The broader lesson applies beyond OpenClaw. Multi-agent platforms tend to market specialization: a security agent, a support agent, a code-review agent, a personal assistant, a project-specific agent. Specialization only works if identity is consistent across runtime metadata, routing, memory, tools, and transcripts. Otherwise, the system is not specialized. It is ambiguously scoped.
PR #93270 is a good fix because it is narrow and testable. It does not try to solve identity philosophy. It removes one false source of authority from the prompt and adds regression coverage around the seam. That is exactly how agent runtimes should mature: not by trusting the model to infer intent from conflicting context, but by making the context boringly correct before the model sees it.
The editorial read is blunt: if the runtime tells an agent it is main, do not blame the model when it believes the runtime. Identity is not what your persona file hopes. Identity is what every layer of the platform consistently says.
Sources: OpenClaw PR #93270, OpenClaw issue #81269, PR file diff and tests