Problem
handleBundle in src/mcp.zig (around line 1715) extracts tool via getStr(op_obj, "tool"). getStr returns null for any non-string JSON value, so a bundle like {"ops":[{"tool":123,"arguments":{...}}]} is reported as missing 'tool' field.
The field is clearly present — it's just the wrong type. Clients chasing the misleading message hunt for a typo or missing key in their request shape that doesn't exist. Several other handlers (getStr, getInt, getBool) have the same problem at the call site, but the bundle one is especially confusing because the bundle is the most likely surface where clients construct ops programmatically and could hit a type mismatch.
Failing Test
Branch: issue-412-failing-test
test "issue-412: bundle reports 'missing tool' for tool field of wrong type" {
var explorer = Explorer.init(testing.allocator);
defer explorer.deinit();
var store = Store.init(testing.allocator);
defer store.deinit();
var agents = AgentRegistry.init(testing.allocator);
defer agents.deinit();
_ = try agents.register("__filesystem__");
var bench_ctx = mcp_mod.BenchContext.init(testing.allocator, ".");
defer bench_ctx.deinit();
const bundle_json =
\\{"ops":[{"tool":123,"arguments":{"path":"x.zig"}}]}
;
const parsed = try std.json.parseFromSlice(std.json.Value, testing.allocator, bundle_json, .{});
defer parsed.deinit();
var out: std.ArrayList(u8) = .empty;
defer out.deinit(testing.allocator);
bench_ctx.runDispatch(io, testing.allocator, .codedb_bundle, &parsed.value.object, &out, &store, &explorer, &agents);
try testing.expect(std.mem.indexOf(u8, out.items, "missing 'tool' field") == null);
}
Expected
Either error: 'tool' must be a string or similar — the diagnostic should reflect that the field is present but wrong type, not pretend it's missing.
Fix
In handleBundle, before calling getStr, distinguish "key absent" from "value is wrong type":
const tool_val = op_obj.get("tool") orelse {
w.print("--- [{d}] error ---\nmissing 'tool' field\n", .{i}) catch {};
fail_count += 1;
continue;
};
const tool_name = switch (tool_val) {
.string => |s| s,
else => {
w.print("--- [{d}] error ---\n'tool' must be a string\n", .{i}) catch {};
fail_count += 1;
continue;
},
};
Problem
handleBundlein src/mcp.zig (around line 1715) extractstoolviagetStr(op_obj, "tool").getStrreturnsnullfor any non-string JSON value, so a bundle like{"ops":[{"tool":123,"arguments":{...}}]}is reported asmissing 'tool' field.The field is clearly present — it's just the wrong type. Clients chasing the misleading message hunt for a typo or missing key in their request shape that doesn't exist. Several other handlers (
getStr,getInt,getBool) have the same problem at the call site, but the bundle one is especially confusing because the bundle is the most likely surface where clients construct ops programmatically and could hit a type mismatch.Failing Test
Branch:
issue-412-failing-testExpected
Either
error: 'tool' must be a stringor similar — the diagnostic should reflect that the field is present but wrong type, not pretend it's missing.Fix
In
handleBundle, before callinggetStr, distinguish "key absent" from "value is wrong type":