microsoft/semantic-kernel · error · ArgumentException

ImageContent must have either Data or a Uri.

Error message

ImageContent must have either Data or a Uri.

What it means

Thrown by GetImageContentItem. An ImageContent is turned into an OpenAI image part either from inline bytes (Data) or from a URI. If Data is empty/null AND Uri is null, the image part cannot be built because OpenAI requires one of the two, so an ArgumentException is raised naming ImageContent.

Source

Thrown at dotnet/src/Connectors/Connectors.OpenAI/Core/ClientCore.ChatCompletion.cs:902

        throw new NotSupportedException($"Role {message.Role} is not supported.");
    }

    private static ChatMessageContentPart GetImageContentItem(ImageContent imageContent)
    {
        ChatImageDetailLevel? detailLevel = GetChatImageDetailLevel(imageContent);

        if (imageContent.Data is { IsEmpty: false } data)
        {
            return ChatMessageContentPart.CreateImagePart(BinaryData.FromBytes(data), imageContent.MimeType, detailLevel);
        }

        if (imageContent.Uri is not null)
        {
            return ChatMessageContentPart.CreateImagePart(imageContent.Uri, detailLevel);
        }

        throw new ArgumentException($"{nameof(ImageContent)} must have either Data or a Uri.");
    }

    private static ChatMessageContentPart GetAudioContentItem(AudioContent audioContent)
    {
        if (audioContent.Data is { IsEmpty: false } data)
        {
            return ChatMessageContentPart.CreateInputAudioPart(BinaryData.FromBytes(data), GetChatInputAudioFormat(audioContent.MimeType));
        }

        throw new ArgumentException($"{nameof(AudioContent)} must have Data bytes.");
    }

    private static ChatMessageContentPart GetBinaryContentItem(BinaryContent binaryContent)
    {
        if (binaryContent.Data is { IsEmpty: false } data)
        {
            return ChatMessageContentPart.CreateFilePart(BinaryData.FromBytes(data), binaryContent.MimeType, Guid.NewGuid().ToString());
        }

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Ensure ImageContent.Data is a non-empty byte buffer, or set ImageContent.Uri to a reachable URL.
  2. After loading bytes, assert data.Length > 0 before constructing ImageContent.
  3. If the source is a URL, prefer the Uri overload of ImageContent.

Example fix

// before
var img = new ImageContent(null, "image/png");
// after
var img = new ImageContent(await File.ReadAllBytesAsync(path), "image/png");
Defensive patterns

Strategy: validation

Validate before calling

static ImageContent BuildImage(byte[]? data, Uri? uri, string mime) { if (data is { Length: > 0 }) return new ImageContent(data, mime); if (uri is not null) return new ImageContent(uri); throw new ArgumentException("ImageContent needs Data or Uri"); }

Type guard

static bool ImageContentIsUsable(ImageContent i) => i.Data is { IsEmpty: false } || i.Uri is not null;

Try / catch

try { await client.GetChatCompletionAsync(history); }
catch (ArgumentException ex) when (ex.Message.Contains("Data or a Uri")) { /* load bytes / set Uri and retry */ }

Prevention

When it happens

Trigger: Constructing ImageContent with neither Data nor Uri set (e.g. only a MimeType), or with an empty Data buffer and no fallback Uri, then including it in a chat message.

Common situations: Loading an image that failed to read (Data stayed empty) and forgetting to set Uri; building ImageContent from metadata only; a stream copy that produced zero bytes.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/d0cb0d759c6bca7d. Report an issue: GitHub.