Skip to content

Commit 7371e95

Browse files
CodeWhale Botclaude
andcommitted
fix(tools): probe the action enum with pointer_mut and guard the Run arm (#5944 follow-up)
Maintainer follow-up on @gaord's fix, applying the two review nits: - The read-only projection probes with schema.pointer_mut("/properties/action/enum"), the same idiom tools/subagent already uses for this exact bug, so the two sites read as one pattern. - The Run arm two lines above still auto-vivified "properties" on a schema without one; it now uses get_mut and cannot write "properties": null. - Rebased onto current main (the tests module had grown a neighbour) and added the changelog receipt crediting the author. RUST_MIN_STACK=16777216 cargo test -p codewhale-tui --lib -- tools::registry: 51 passed; 0 failed. cargo fmt --check clean; cargo clippy -p codewhale-tui --lib --all-targets -D warnings clean; sync-changelog --check clean. No-Issue: community fix from a live Fleet 400 report; no tracking issue. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SJrzNAmppg4vt3LNJbaeri Signed-off-by: CodeWhale Bot <bot@codewhale.net>
1 parent d691b0d commit 7371e95

4 files changed

Lines changed: 26 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,14 @@ Reports and reproductions that shaped this release:
477477

478478
### Fixed
479479

480+
- Read-only Fleet workers no longer send `"action": {"enum": null}` in their
481+
projected `bash` schema. The read-only projection probed the action enum
482+
with a mutating index, which auto-vivified the key on schemas that have no
483+
action property, and strict OpenAI-compatible validators then rejected the
484+
whole request (`null is not of type "array"`). The probe is non-mutating
485+
now, in both the read-only projection and the `Run` arm next to it, and a
486+
regression test walks the whole projected catalog for nulls
487+
(#5944, thanks @gaord).
480488
- Fast typing no longer corrupts the composer. The paste-burst heuristic ran
481489
on every session until a real bracketed paste arrived, holding, buffering,
482490
retro-grabbing, and absorbing Enter on timing guesses; it is now

crates/tui/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,14 @@ Reports and reproductions that shaped this release:
477477

478478
### Fixed
479479

480+
- Read-only Fleet workers no longer send `"action": {"enum": null}` in their
481+
projected `bash` schema. The read-only projection probed the action enum
482+
with a mutating index, which auto-vivified the key on schemas that have no
483+
action property, and strict OpenAI-compatible validators then rejected the
484+
whole request (`null is not of type "array"`). The probe is non-mutating
485+
now, in both the read-only projection and the `Run` arm next to it, and a
486+
regression test walks the whole projected catalog for nulls
487+
(#5944, thanks @gaord).
480488
- Fast typing no longer corrupts the composer. The paste-burst heuristic ran
481489
on every session until a real bracketed paste arrived, holding, buffering,
482490
retro-grabbing, and absorbing Enter on timing guesses; it is now

crates/tui/src/tools/registry.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -505,25 +505,24 @@ fn project_readonly_evidence_schema(name: &str, schema: &mut Value) {
505505
if name == "Run" {
506506
// The shared classifier remains authoritative for `args`; the schema
507507
// removes the only field that can name verifier programs.
508-
if let Some(properties) = schema["properties"].as_object_mut() {
508+
if let Some(properties) = schema.get_mut("properties").and_then(Value::as_object_mut) {
509509
properties.remove("commands");
510510
}
511511
return;
512512
}
513-
// Probe with `get_mut`, never `schema["properties"]["action"]["enum"]`:
513+
// Probe with `pointer_mut`, never `schema["properties"]["action"]["enum"]`:
514514
// serde_json's IndexMut auto-vivifies missing keys by inserting Null, so
515515
// the old probe left `properties.action = {"enum": null}` inside schemas
516516
// that have no action property (e.g. lowercase `bash`). Strict
517517
// OpenAI-compatible validators then reject the whole request with
518518
// `Invalid schema for function 'bash': null is not of type "array"`
519519
// (observed on Fleet read-only workers; see registry tests).
520-
let Some(properties) = schema.get_mut("properties").and_then(Value::as_object_mut) else {
521-
return;
522-
};
523-
let Some(action) = properties.get_mut("action") else {
524-
return;
525-
};
526-
let Some(actions) = action.get_mut("enum").and_then(Value::as_array_mut) else {
520+
// The same probe idiom lives in `tools/subagent` (grep `pointer_mut(
521+
// "/properties/action/enum")`); keep the two sites greppable as one.
522+
let Some(actions) = schema
523+
.pointer_mut("/properties/action/enum")
524+
.and_then(Value::as_array_mut)
525+
else {
527526
return;
528527
};
529528
match name {

crates/tui/src/tools/registry/tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,8 @@ fn a_builder_upgrade_replaces_the_tool_instead_of_registering_it_twice() {
18021802
.any(|tool| tool.name() == "apply_patch"),
18031803
"the upgrade still adds apply_patch"
18041804
);
1805+
}
1806+
18051807
/// Regression probe for the fleet-52663788 class of provider 400
18061808
/// (`Invalid schema for function 'bash': null is not of type "array"`):
18071809
/// a read-only Fleet worker (reviewer) projects its tool schemas before the

0 commit comments

Comments
 (0)