Skip to content

config patch/set coerce numeric-string object keys into array indices #83331

@cdeyoung67

Description

@cdeyoung67

Summary

openclaw config patch and openclaw config set coerce all-digit string keys into array indices. This breaks valid Record-typed config paths such as channels.discord.guilds, where Discord snowflake IDs are string keys but look numeric.

Environment

  • OpenClaw version: 2026.5.7
  • Install path: native install via the official one-liner
  • Host OS: Ubuntu 24.04

Reproduction

Create two minimal patch files:

cat > /tmp/probe-array.json5 <<'EOF1'
{ channels: { discord: { guilds: { "1495587801394184362": { requireMention: true } } } } }
EOF1
cat > /tmp/probe-string.json5 <<'EOF2'
{ channels: { discord: { guilds: { "test-guild": { requireMention: true } } } } }
EOF2

Then run:

openclaw config patch --dry-run /tmp/probe-array.json5
openclaw config patch --dry-run /tmp/probe-string.json5
openclaw config set "channels.discord.guilds.1495587801394184362.requireMention" true

Expected

Numeric-looking string keys should remain string keys for Record/object fields. Both patch and set operations should preserve the object shape of channels.discord.guilds.

Actual

The numeric-key patch fails validation:

Error: Config validation failed: channels.discord.guilds: invalid config: must be object

The non-numeric key patch passes, which suggests the failure is caused by numeric-key coercion rather than the value shape.

config set shows the same class of failure for the same reason.

Why this matters

Discord guild IDs are all-digit strings by design. Any Record-typed config that accepts numeric IDs becomes hard or impossible to write through the CLI patch/set path, even though the on-disk JSON shape is valid and the runtime reader handles it correctly.

Suggested fix

  • Preserve key types from JSON/JSON5 input for Record/object schema fields.
  • Do not apply array-index heuristics to object keys solely because they are all digits.
  • Ensure config set path parsing can target string-keyed object members whose keys are numeric strings.

Notes

AoAOS workaround: write the final config atomically with Python/JSON instead of using the CLI patch path.
Source doc:

  • docs/upstream-bugs/config-patch-numeric-key-array-coercion.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions