fix(cron): accept null fallbacks in update patch payload (#100707) (#100801)

* fix(cron): accept null fallbacks in cron update patch payload

createCronPatchObjectSchema passes nullableStringArraySchema for model and
toolsAllow, but fallbacks was still hardcoded as a non-nullable array in
cronPayloadObjectSchema, rejecting null clears before they reach the
Gateway service layer.

Switch fallbacks to a parameter so the patch context can pass the nullable
variant, matching the existing pattern for model and toolsAllow.

Fixes #100707

Co-Authored-By: Claude <noreply@anthropic.com>

* test(cron): cover model+fallbacks null clear in patch schema test

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
SunnyShu
2026-07-06 21:48:00 +08:00
committed by GitHub
parent e35c7a3c95
commit a98a64649e
8 changed files with 71 additions and 29 deletions
@@ -904,11 +904,18 @@
"type": "boolean"
},
"fallbacks": {
"description": "Fallback models",
"items": {
"type": "string"
},
"type": "array"
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"description": "Fallback models, or null to clear"
},
"kind": {
"description": "Payload kind",
@@ -900,11 +900,18 @@
"type": "boolean"
},
"fallbacks": {
"description": "Fallback models",
"items": {
"type": "string"
},
"type": "array"
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"description": "Fallback models, or null to clear"
},
"kind": {
"description": "Payload kind",
@@ -900,11 +900,18 @@
"type": "boolean"
},
"fallbacks": {
"description": "Fallback models",
"items": {
"type": "string"
},
"type": "array"
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"description": "Fallback models, or null to clear"
},
"kind": {
"description": "Payload kind",
@@ -227,8 +227,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 0
},
"dynamicToolsJson": {
"chars": 51703,
"roughTokens": 12926
"chars": 51940,
"roughTokens": 12985
},
"openClawDeveloperInstructions": {
"chars": 3045,
@@ -239,8 +239,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 6893
},
"totalWithDynamicToolsJson": {
"chars": 79275,
"roughTokens": 19819
"chars": 79512,
"roughTokens": 19878
},
"userInputText": {
"chars": 1442,
@@ -227,8 +227,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 0
},
"dynamicToolsJson": {
"chars": 51392,
"roughTokens": 12848
"chars": 51629,
"roughTokens": 12908
},
"openClawDeveloperInstructions": {
"chars": 1936,
@@ -239,8 +239,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 6513
},
"totalWithDynamicToolsJson": {
"chars": 77446,
"roughTokens": 19362
"chars": 77683,
"roughTokens": 19421
},
"userInputText": {
"chars": 1033,
@@ -228,8 +228,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 0
},
"dynamicToolsJson": {
"chars": 52682,
"roughTokens": 13171
"chars": 52919,
"roughTokens": 13230
},
"openClawDeveloperInstructions": {
"chars": 1955,
@@ -240,8 +240,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 6749
},
"totalWithDynamicToolsJson": {
"chars": 79679,
"roughTokens": 19920
"chars": 79916,
"roughTokens": 19979
},
"userInputText": {
"chars": 1271,