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
- Do not mutate a BinaryContent instance concurrently with serializing it; treat it as immutable once passed to the kernel.
- Construct a fresh BinaryContent per request instead of reusing/clearing one.
- 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
- Treat BinaryContent as immutable once passed to the kernel.
- Never share and mutate a BinaryContent across parallel requests.
- Build a fresh BinaryContent per request.
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
- Audio content URI is empty.
- Binary content does not contain any data or uri.
- Binary content MimeType is empty.
- Runtime is already stopping.
- MaxTokens {maxTokens} is not valid, the value must be greate
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/0820f82ea114493b.
Report an issue: GitHub.