openclaw - ✅(Solved) Fix [Bug]: agents.create RPC ignores model param and writes identity to IDENTITY.md instead of config [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

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#61559Fetched 2026-04-08 02:57:20
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×1mentioned ×1subscribed ×1

agents.create and agents.update RPC methods have two related issues:

  1. Identity write path mismatch: Both methods write emoji/avatar into IDENTITY.md (workspace file) via text append, but agents.list reads identity exclusively from agents.list[].identity in config. This means identity fields set during create/update are invisible to the list response and Control UI.

  2. agents.create missing model param: agents.update accepts model and persists it via applyAgentConfig(), but agents.create does not — even though applyAgentConfig() already supports it. New agents must call update immediately after create to set a model override.

Root Cause

agents.create and agents.update RPC methods have two related issues:

  1. Identity write path mismatch: Both methods write emoji/avatar into IDENTITY.md (workspace file) via text append, but agents.list reads identity exclusively from agents.list[].identity in config. This means identity fields set during create/update are invisible to the list response and Control UI.

  2. agents.create missing model param: agents.update accepts model and persists it via applyAgentConfig(), but agents.create does not — even though applyAgentConfig() already supports it. New agents must call update immediately after create to set a model override.

Fix Action

Fixed

PR fix notes

PR #61577: [Fix] agents.create RPC: support model param, write identity to config

Description (problem / solution / changelog)

Summary

  • Problem: agents.create RPC didn't accept model param, forcing a follow-up agents.update call to set model at creation time.
  • Problem: Create/update handlers wrote identity fields (name, emoji, avatar) to IDENTITY.md but agents.list (gateway) reads from agents.list[].identity in config — data was silently invisible to the control UI.
  • Why it matters: New agents created via RPC had no visible identity or model in the control UI without workaround calls.
  • What changed: Added model to create schema, emoji to update schema. Replaced IDENTITY.md file I/O with config identity writes via applyAgentConfig. Removed dead helpers (ensureWorkspaceFileReadyOrRespond, appendWorkspaceFileOrRespond). Added unit tests for identity merge logic.
  • What did NOT change (scope boundary): IDENTITY.md bootstrap (still created by ensureAgentWorkspace), avatar upload endpoint, IDENTITY.md removal/migration.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #61559
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: agents.create was shipped without model param (v1 scope cut). Identity write path targeted IDENTITY.md (workspace file) but the gateway list endpoint reads identity from config, creating a silent data divergence.
  • Missing detection / guardrail: No test asserted that RPC-created agent identity was readable through the gateway list endpoint.
  • Contributing context (if known): The CLI set-identity command correctly writes to config; the RPC handlers predated that alignment.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/commands/agents.test.ts, src/gateway/server-methods/agents-mutate.test.ts
  • Scenario the test should lock in: applyAgentConfig merges identity fields correctly; create/update handlers pass identity and model to config instead of IDENTITY.md.
  • Why this is the smallest reliable guardrail: Unit tests verify the merge logic and handler wiring without requiring a running gateway.
  • Existing test that already covers this (if any): Handler tests existed but asserted IDENTITY.md writes; updated to assert config writes.
  • If no new test is added, why not: Two new unit tests added for applyAgentConfig identity merge.

User-visible / Behavior Changes

  • agents.create now accepts optional model param and returns it in the response.
  • agents.update now accepts optional emoji param.
  • Identity fields (name, emoji, avatar) set via RPC are now visible in agents.list and the control UI.

Diagram (if applicable)

Before:
[agents.create name/emoji/avatar] -> [IDENTITY.md] (gateway reads config -> invisible)

After:
[agents.create name/emoji/avatar/model] -> [config.agents.list[].identity] (gateway reads config -> visible)

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / Bun
  • Model/provider: N/A
  • Integration/channel (if any): Gateway RPC
  • Relevant config (redacted): N/A

Steps

  1. Call agents.create with name, model, emoji params
  2. Call agents.list
  3. Verify created agent has correct identity and model

Expected

  • Agent appears in list with name, emoji, and model set

Actual

  • Before fix: identity fields missing from list, model not accepted
  • After fix: all fields present

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

38 tests passing (2 files: agents.test.ts, agents-mutate.test.ts)

Human Verification (required)

  • Verified scenarios: All 38 unit tests pass. Traced all 3 identity read paths (resolveAssistantIdentity, listAgentsForGateway, listConfiguredAgents) — all have config fallback. Verified all 7 applyAgentConfig callers are backwards-compatible.
  • Edge cases checked: Identity merge preserves unmentioned fields (theme). Empty emoji/avatar dropped by resolveOptionalStringParam. Name sanitized consistently via sanitizeIdentityLine for both entry.name and identity.name.
  • What you did not verify: Live gateway RPC round-trip (unit tests only).

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes (additive optional fields only)
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: IDENTITY.md no longer updated by RPC — bootstrap file stays as template for RPC-created agents.
    • Mitigation: By design. resolveAssistantIdentity reads config identity first, falling back to file. Aligns with CLI set-identity behavior. IDENTITY.md remains as agent self-discovery bootstrap file.

Changed files

  • src/commands/agents.config.ts (modified, +4/-0)
  • src/commands/agents.test.ts (modified, +33/-0)
  • src/gateway/protocol/schema/agents-models-skills.ts (modified, +3/-0)
  • src/gateway/server-methods/agents-mutate.test.ts (modified, +51/-88)
  • src/gateway/server-methods/agents.ts (modified, +33/-108)
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

agents.create and agents.update RPC methods have two related issues:

  1. Identity write path mismatch: Both methods write emoji/avatar into IDENTITY.md (workspace file) via text append, but agents.list reads identity exclusively from agents.list[].identity in config. This means identity fields set during create/update are invisible to the list response and Control UI.

  2. agents.create missing model param: agents.update accepts model and persists it via applyAgentConfig(), but agents.create does not — even though applyAgentConfig() already supports it. New agents must call update immediately after create to set a model override.

Steps to reproduce

  1. Call agents.create with { name: "test", workspace: "/tmp/test", emoji: "🤖" }
  2. Call agents.list
  3. Observe: the created agent has identity: undefined in the list response
  4. Check IDENTITY.md in workspace: emoji is written there but never read by agents.list

For model:

  1. Call agents.create with any params — no model field accepted
  2. Must call agents.update with { agentId: "test", model: "some-model" } separately

Expected behavior

  • agents.create should accept model and persist it to config (like agents.update does)
  • agents.create and agents.update should persist identity fields to agents.list[].identity in config (like CLI set-identity does), not append to IDENTITY.md
  • agents.list should reflect identity/model set during creation without requiring a separate update call

Actual behavior

  • agents.create does not accept model
  • Identity written to IDENTITY.md is invisible to agents.list (reads from config only)
  • agents.update has the same identity write path issue for avatar

OpenClaw version

2026.4 (main)

Operating system

All

Install method

npm global / pnpm dev

Model

N/A — this is a gateway RPC schema/handler issue independent of model selection

Provider / routing chain

N/A — the bug is in the gateway agent mutation RPC layer, before any provider or model routing

Logs, screenshots, and evidence

Schema comparison from source (src/gateway/protocol/schema/agents-models-skills.ts):

Fieldagents.createagents.updateagents.list response
model❌ missing✅ optional✅ present
emoji✅ optional (writes IDENTITY.md)❌ missing✅ (from config)
avatar✅ optional (writes IDENTITY.md)✅ optional (writes IDENTITY.md)✅ (from config)
identity (structured)❌ flat write❌ flat write✅ nested object

Write path divergence:

  • agents.create handler → appends to IDENTITY.md (line 601-606 of agents.ts)
  • agents.list handler → reads from cfg.agents.list[].identity (line 643 of session-utils.ts)
  • CLI set-identity → writes to cfg.agents.list[].identity (canonical path)

Impact and severity

  • Affected: Control UI agent creation/editing workflows; any RPC client using agents.create
  • Severity: Medium — identity set during create is silently lost (invisible to list); model requires extra update call
  • Frequency: Always reproducible
  • Consequence: Control UI shows agents without identity after creation; extra roundtrip required to set model

Additional information

  • PR #11045 introduced agents.create/update/delete as a v1 for the Control UI
  • PR #11603 by @advaitpaliwal attempted to fix the identity write path (persist to config instead of IDENTITY.md) but was closed as stale without merging
  • The CLI openclaw agents set-identity correctly writes to config — the RPC handlers should align with this canonical path

extent analysis

TL;DR

Update the agents.create and agents.update RPC methods to persist identity fields to agents.list[].identity in config, and add model as an accepted parameter to agents.create.

Guidance

  • Modify the agents.create handler to accept a model parameter and persist it to config using applyAgentConfig().
  • Update both agents.create and agents.update handlers to write identity fields (e.g., emoji, avatar) to agents.list[].identity in config, rather than appending to IDENTITY.md.
  • Verify the changes by calling agents.create with a model parameter and checking that the created agent's identity is visible in the agents.list response.
  • Test the updated agents.update handler to ensure it correctly persists identity fields to config.

Example

// Example of updated agents.create handler
const createAgent = async (agentData) => {
  // ...
  if (agentData.model) {
    await applyAgentConfig(agentId, { model: agentData.model });
  }
  // Write identity fields to config
  const identity = {
    emoji: agentData.emoji,
    avatar: agentData.avatar,
  };
  await updateAgentConfig(agentId, { identity });
  // ...
};

Notes

The provided solution focuses on aligning the agents.create and agents.update handlers with the canonical path used by the CLI set-identity command. This should resolve the identity write path mismatch and allow agents.create to accept a model parameter.

Recommendation

Apply the workaround by updating the agents.create and agents.update handlers as described, to ensure consistent behavior and data visibility in the Control UI and RPC clients.

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…

FAQ

Expected behavior

  • agents.create should accept model and persist it to config (like agents.update does)
  • agents.create and agents.update should persist identity fields to agents.list[].identity in config (like CLI set-identity does), not append to IDENTITY.md
  • agents.list should reflect identity/model set during creation without requiring a separate update call

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 - ✅(Solved) Fix [Bug]: agents.create RPC ignores model param and writes identity to IDENTITY.md instead of config [1 pull requests, 1 participants]