name the field when sampling content is missing (#689)
Follow-up to [this thread](https://github.com/dart-lang/ai/pull/685#discussion_r4063946725) on #685.
A `SamplingMessage` without `content` now throws an `ArgumentError` naming the field, instead of a `TypeError` from the cast. Its wording follows the other missing-field checks under `lib/src/api/`.
diff --git a/pkgs/dart_mcp/CHANGELOG.md b/pkgs/dart_mcp/CHANGELOG.md
index 8db24e2..bd3b70d 100644
--- a/pkgs/dart_mcp/CHANGELOG.md
+++ b/pkgs/dart_mcp/CHANGELOG.md
@@ -151,8 +151,9 @@
- `SamplingMessage.content` and `CreateMessageResult.content` now read
`List<SamplingMessageContentBlock>` instead of `Content`. The schema
allows one block or a list of them under `content`; both shapes read as a
- list, and one block still goes on the wire as that block. `TextContent`,
- `ImageContent` and `AudioContent` implement both types.
+ list, and one block still goes on the wire as that block. A missing
+ `content` throws an `ArgumentError`. `TextContent`, `ImageContent` and
+ `AudioContent` implement both types.
`ToolUseContent` and `ToolResultContent` implement only the new one,
keeping a plain `tools/call` result from carrying tool content by
accident. `ToolResultContent.content` still reads `List<Content>`,
diff --git a/pkgs/dart_mcp/lib/src/api/sampling.dart b/pkgs/dart_mcp/lib/src/api/sampling.dart
index f381b7a..ec5f2be 100644
--- a/pkgs/dart_mcp/lib/src/api/sampling.dart
+++ b/pkgs/dart_mcp/lib/src/api/sampling.dart
@@ -178,6 +178,9 @@
/// read as a list here. One block comes back as a single-element list.
List<SamplingMessageContentBlock> get content {
final content = _value[Keys.content];
+ if (content == null) {
+ throw ArgumentError('Missing ${Keys.content} field in $SamplingMessage.');
+ }
if (content is List) {
return content.cast<SamplingMessageContentBlock>();
}
diff --git a/pkgs/dart_mcp/test/api/sampling_test.dart b/pkgs/dart_mcp/test/api/sampling_test.dart
index e3dfde6..e2d9d18 100644
--- a/pkgs/dart_mcp/test/api/sampling_test.dart
+++ b/pkgs/dart_mcp/test/api/sampling_test.dart
@@ -81,6 +81,13 @@
expect((parsed.content.single as TextContent).text, 'merhaba');
});
+ test('SamplingMessage throws when content is missing', () {
+ expect(
+ () => SamplingMessage.fromMap({'role': 'user'}).content,
+ throwsArgumentError,
+ );
+ });
+
test('CreateMessageResult accepts a SamplingMessageContentBlock', () {
final block = SamplingMessageContentBlock.toolResult(
toolUseId: 'call-2',