microsoft/semantic-kernel · info · InvalidOperationException

Binary content URI is empty.

Error message

Binary content URI is empty.

What it means

Thrown by CreateGeminiPartFromBinary when building a FileDataPart for a BinaryContent that has a URI. The binaryContent.Uri ?? throw guards against a null URI but sits inside an 'if (binaryContent.Uri is not null)' block, so it is effectively unreachable defensive code. It would only fire under concurrent mutation of the content object during serialization.

Source

Thrown at dotnet/src/Connectors/Connectors.Google/Core/Gemini/Models/GeminiRequest.cs:411

        {
            return new GeminiPart
            {
                InlineData = new GeminiPart.InlineDataPart
                {
                    MimeType = GetMimeTypeFromBinaryContent(binaryContent),
                    InlineData = Convert.ToBase64String(binaryContent.Data.Value.ToArray())
                }
            };
        }

        if (binaryContent.Uri is not null)
        {
            return new GeminiPart
            {
                FileData = new GeminiPart.FileDataPart
                {
                    MimeType = GetMimeTypeFromBinaryContent(binaryContent),
                    FileUri = binaryContent.Uri ?? throw new InvalidOperationException("Binary content URI is empty.")
                }
            };
        }

        throw new InvalidOperationException("Binary content does not contain any data or uri.");
    }

    private static string GetMimeTypeFromBinaryContent(BinaryContent binaryContent)
    {
        return binaryContent.MimeType
               ?? throw new InvalidOperationException("Binary content MimeType is empty.");
    }

    private static void AddConfiguration(GeminiPromptExecutionSettings executionSettings, GeminiRequest request)
    {
        request.Configuration = new ConfigurationElement
        {
            Temperature = executionSettings.Temperature,

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Do not mutate a BinaryContent instance concurrently with serializing it; treat it as immutable once passed to the kernel.
  2. Construct a fresh BinaryContent per request instead of reusing/clearing one.
  3. Audit shared-content patterns across parallel invocations.

Example fix

// before (race)
var bin = new BinaryContent(uri: myUri, mimeType: "application/octet-stream");
// task A serializes bin; task B sets bin.Uri = null

// after
var bin = new BinaryContent(uri: myUri, mimeType: "application/octet-stream");
await kernel.InvokeAsync(... bin ...);  // no concurrent mutation
Defensive patterns

Strategy: validation

Validate before calling

// Validate BinaryContent immutability before invoking
static bool IsBinaryContentSafe(BinaryContent c)
    => c.Uri is not null && !string.IsNullOrEmpty(c.MimeType);
// Ensure no concurrent mutation of c.Uri during the call.

Prevention

When it happens

Trigger: Only fires if binaryContent.Uri is reset to null between the 'is not null' check (line 404) and the FileUri assignment (line 411) — a race condition on a shared, mutated BinaryContent.

Common situations: Reusing a single BinaryContent across parallel tasks where one clears the Uri while another serializes. Never occurs in single-threaded code.

Related errors


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