Skip to content

Commit 6c2b902

Browse files
authored
fix: validate content items and require data field in binary content (#5238)
## Problem Two unit tests in `internal/mcp/tool_result_test.go` fail: - **`TestDecodeContentData/missing_image_data_returns_error`** — `decodeContentData` silently returns `nil, nil` when the `data` field is missing, but the test expects an error. - **`TestConvertMapToCallToolResult_ContentItemCastFailure`** — non-map entries in `[]interface{}` content arrays are silently dropped instead of causing an error. ## Fix 1. **`decodeContentData`**: Now checks for the presence of the `data` key and returns a descriptive error when it's missing or nil, preventing corrupted backend responses from surfacing as empty media. 2. **`ConvertToCallToolResult`**: Now rejects non-map entries in `[]interface{}` content arrays with an error instead of silently dropping them, preventing data loss from malformed responses. ## Verification `make agent-finished` passes — all unit and integration tests green.
2 parents 5d2e312 + 5729f8f commit 6c2b902

2 files changed

Lines changed: 11 additions & 5 deletions

File tree

internal/mcp/tool_result.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,12 @@ func convertMapToCallToolResult(m map[string]interface{}) (*sdk.CallToolResult,
7272
switch v := contentVal.(type) {
7373
case []interface{}:
7474
items = make([]map[string]interface{}, 0, len(v))
75-
for _, item := range v {
76-
if ci, ok := item.(map[string]interface{}); ok {
77-
items = append(items, ci)
75+
for i, item := range v {
76+
ci, ok := item.(map[string]interface{})
77+
if !ok {
78+
return nil, fmt.Errorf("content item %d: expected map, got %T", i, item)
7879
}
80+
items = append(items, ci)
7981
}
8082
case []map[string]interface{}:
8183
items = v
@@ -155,13 +157,17 @@ func convertContentItem(ci map[string]interface{}) (sdk.Content, error) {
155157
// When data arrives via json.Unmarshal into interface{}, []byte fields are stored as
156158
// base64 strings; this function handles both the string and pre-decoded []byte forms.
157159
func decodeContentData(ci map[string]interface{}) ([]byte, error) {
158-
switch v := ci["data"].(type) {
160+
raw, exists := ci["data"]
161+
if !exists || raw == nil {
162+
return nil, fmt.Errorf("missing required 'data' field")
163+
}
164+
switch v := raw.(type) {
159165
case []byte:
160166
return v, nil
161167
case string:
162168
return base64.StdEncoding.DecodeString(v)
163169
default:
164-
return nil, nil
170+
return nil, fmt.Errorf("unsupported data type %T", raw)
165171
}
166172
}
167173

165 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)