openclaw - ✅(Solved) Fix cron edit: toolsAllow rejected as unexpected property in payload patch [1 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

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#59211Fetched 2026-04-08 02:27:29
View on GitHub
Comments
2
Participants
3
Timeline
5
Reactions
0
Timeline (top)
cross-referenced ×3commented ×2

Error Message

GatewayClientRequestError: invalid cron.update params: at /patch/payload: unexpected property 'toolsAllow'; at /patch/payload/kind: must be equal to constant; at /patch/payload: must match a schema in anyOf

Root Cause

Root Cause (suspected)

Fix Action

Workaround

None found. --clear-tools flag also routes through the same payload path. Waiting for patch.

PR fix notes

PR #62675: fix: forward optional params dropped at the runEmbeddedAttempt call site

Description (problem / solution / changelog)

Summary

toolsAllow set on a cron agentTurn payload has no effect at runtime — the model still receives the complete tool catalog (all built-in + all MCP plugin tools) on every run, because runEmbeddedPiAgent does not forward params.toolsAllow to its runEmbeddedAttempt call. The CLI/persistence layers work correctly; only the runtime plumbing was missing.

Fixes #62569

Why it matters

PR #58504 (closes #58435) added --tools / payload.toolsAllow for per-job tool allowlists, with a stated motivation of making small local models usable for focused cron tasks. The PR's writeup advertised a ~95% input-token reduction (~16K → ~800) when a single-tool restriction is applied. docs/automation/cron-jobs.md:85 documents the same intent:

--tools exec,read: restrict which tools the job can use

But on the runtime path, the value is silently dropped before reaching the consumer, so the documented behavior never takes effect. Affects every cron agentTurn job that sets toolsAllow (or uses --tools).

Root cause

runEmbeddedPiAgent (in src/agents/pi-embedded-runner/run.ts) hand-enumerates ~80 fields when calling runEmbeddedAttempt({...}). PR #58504 wired toolsAllow through:

  • cron/isolated-agent/run-executor.ts:132 — cron payload → runEmbeddedPiAgent
  • pi-embedded-runner/run/params.ts:103 — added to RunEmbeddedPiAgentParams
  • pi-embedded-runner/run/attempt.ts:523-525 — consumer filter ready ✅
  • pi-embedded-runner/run.ts runEmbeddedAttempt({...}) callnever wired

toolsAllow is declared as ?: optional on EmbeddedRunAttemptParams (via Omit<RunEmbeddedPiAgentParams, ...> in run/types.ts:13-16), so TypeScript does not flag the missing field at the object literal. The attempt silently receives undefined and the filter at attempt.ts:523-525 is never entered.

This is the same plumbing gap that #62264 (f1b7dd6c0a, "fix: honor lightContext in spawned subagents") fixed for bootstrapContextMode and bootstrapContextRunKind at the same call site. PR #62264 was scoped to subagent lightContext; the toolsAllow field was adjacent in the same hand-listed object literal but not included in that fix. PRs #60776 and #56484 (now closed) had previously identified the bootstrap* half of the same gap.

Fix

One additional line in the runEmbeddedAttempt({...}) call in src/agents/pi-embedded-runner/run.ts, immediately after the lines added by #62264:

bootstrapContextMode: params.bootstrapContextMode,
bootstrapContextRunKind: params.bootstrapContextRunKind,
toolsAllow: params.toolsAllow,

Test plan

A new file src/agents/pi-embedded-runner/run.attempt-param-forwarding.test.ts exercises the field-forwarding seam end-to-end via the existing loadRunOverflowCompactionHarness() (which mocks runEmbeddedAttempt and lets us call the real runEmbeddedPiAgent). It contains three tests, one per optional param that's been bitten by this class of bug:

  • forwards toolsAllow so the per-job tool allowlist can be honoredfails on main before the fix, passes after.
  • forwards bootstrapContextMode so lightContext cron jobs strip workspace bootstrap files — guardrail for #62264.
  • forwards bootstrapContextRunKind so the bootstrap filter knows the caller context — guardrail for #62264.

The two bootstrapContext* tests are deliberately included so the next ?: optional field added to RunEmbeddedPiAgentParams without wiring at this call site will fail a test instead of silently shipping broken — same gap PR #60776's writeup explicitly called out as missing detection.

Verified locally

pnpm test src/agents/pi-embedded-runner/run.attempt-param-forwarding.test.ts
  ✓ forwards toolsAllow so the per-job tool allowlist can be honored
  ✓ forwards bootstrapContextMode so lightContext cron jobs strip workspace bootstrap files
  ✓ forwards bootstrapContextRunKind so the bootstrap filter knows the caller context
  Test Files  1 passed (1)
       Tests  3 passed (3)

pnpm test src/agents/pi-embedded-runner/run
  Test Files  21 passed (21)
       Tests  258 passed (258)

pnpm test src/cron/isolated-agent
  Test Files  18 passed (18)
       Tests  176 passed (176)

node scripts/run-oxlint.mjs
  Found 0 warnings and 0 errors. (10595 files, 136 rules)

node scripts/run-tsgo.mjs
  exit 0

End-to-end verification on a real cron

Verified against the actual cron path with a haiku probe (so the full request payload could be inspected, since the payload logger only records Anthropic requests). Same payload.toolsAllow: ["lobster"] cron, before/after applying the same forwarding gap fix:

MetricBefore fixAfter fixNotes
System prompt length61,954 chars31,533 charsbootstrap files stripped (lightContext working post-#62264)
Tool count in request721 (with this PR)toolsAllow honored

Without this PR, the toolsAllow: ["lobster"] setting is observable in jobs.json but ignored at runtime, and the request still ships all 72 registered tools. With this PR applied, only the listed tool reaches the model.

Scope boundary

Intentionally not in this PR:

  • attempt.ts:549-572 (bundle MCP / LSP tool merge): even with this fix, plugin-contributed tools are spread into effectiveTools after the toolsAllow filter, so --tools exec would still ship all installed plugin tools (lossless-claw, engram, work, shared, etc.). That's a scope-of-filter design question (should toolsAllow restrict plugin tools too?) rather than a plumbing bug, and deserves its own discussion. Filed as a separate concern in issue #62569.
  • No changes to the cron write path, the cron edit --tools schema (#59211 covers that), the bootstrap filter, the system prompt builder, or any plugin SDK surface.

Linked work

  • Fixes: #62569 (the issue documenting this bug end-to-end)
  • Related: #58504 (closed, original toolsAllow feature implementation), #58435 (closed, original feature request), #62264 (merged, sister bootstrapContextMode / bootstrapContextRunKind forwarding fix at the same call site)
  • Superseded by #62264: #60776, #56484 (both now closed) — same call site, same ?: optional plumbing gap class

cc @claygeo per the offer in #56484 and @theSamPadilla per the related work in #62264 — feedback welcome from either of you on the regression test shape, since this is the kind of guardrail #60776's writeup explicitly noted as missing.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/pi-embedded-runner/run.attempt-param-forwarding.test.ts (added, +80/-0)
  • src/agents/pi-embedded-runner/run.ts (modified, +4/-0)

Code Example

GatewayClientRequestError: invalid cron.update params: at /patch/payload: unexpected property 'toolsAllow'; at /patch/payload/kind: must be equal to constant; at /patch/payload: must match a schema in anyOf

---

payload.toolsAllow = opts.tools.split(",").map((t) => t.trim()).filter(Boolean);
RAW_BUFFERClick to expand / collapse

Bug

openclaw cron edit <id> --tools "exec,read" fails with:

GatewayClientRequestError: invalid cron.update params: at /patch/payload: unexpected property 'toolsAllow'; at /patch/payload/kind: must be equal to constant; at /patch/payload: must match a schema in anyOf

Version

OpenClaw 2026.4.1 (da64a97)

Steps to Reproduce

  1. Have an existing cron job (e.g. c90f142c)
  2. Run: openclaw cron edit c90f142c --tools "exec,read"
  3. Observe the validation error

Also fails via the gateway RPC tool when patching payload.toolsAllow directly.

Root Cause (suspected)

The CLI (cron-cli-BBHRXUsj.js) places toolsAllow inside the payload object:

payload.toolsAllow = opts.tools.split(",").map((t) => t.trim()).filter(Boolean);

But the gateway update schema for payload does not include toolsAllow as an accepted property, so Ajv rejects it.

The cron add path appears to have the same issue — toolsAllow is documented as a job-level field but the CLI nests it inside payload.

Expected Behavior

--tools "exec,read" should set toolsAllow at the correct schema level (job root or payload, whichever is canonical) and the gateway update validator should accept it.

Workaround

None found. --clear-tools flag also routes through the same payload path. Waiting for patch.

extent analysis

TL;DR

The issue can be resolved by modifying the CLI to place the toolsAllow property at the correct schema level, which is likely at the job root level instead of inside the payload object.

Guidance

  • Review the gateway update schema to confirm the correct location for the toolsAllow property.
  • Update the cron-cli-BBHRXUsj.js file to move the toolsAllow property outside of the payload object, if that is the correct schema level.
  • Verify that the cron add path also correctly places the toolsAllow property to ensure consistency.
  • Test the updated CLI with the --tools flag to ensure that the validation error is resolved.

Example

// Updated code to place toolsAllow at the job root level
const job = {
  // ... other job properties ...
  toolsAllow: opts.tools.split(",").map((t) => t.trim()).filter(Boolean),
  payload: {
    // ... other payload properties ...
  }
}

Notes

The exact fix may depend on the specifics of the gateway update schema, which is not provided in the issue. Additionally, the cron add path may need to be updated in a similar way to ensure consistency.

Recommendation

Apply workaround: Update the CLI to correctly place the toolsAllow property, as this is a targeted fix that addresses the specific issue.

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…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING