Devolutions/UniGetUI · warning · InvalidOperationException
Exactly one of content or path must be supplied when importi
Error message
Exactly one of content or path must be supplied when importing a bundle.
What it means
ReadBundleContentAsync (called by ImportBundleAsync) requires exactly one source for the bundle data: either request.Content (inline string) or request.Path (file path). It computes hasContent and hasPath as non-whitespace checks and throws InvalidOperationException when both are true (ambiguous) or both are false (nothing to import). This is a mutually-exclusive input contract.
Source
Thrown at src/UniGetUI.Interface.IpcApi/IpcBundleApi.cs:483
return (await imported.AsSerializableAsync()).Version;
}
if (package is InvalidImportedPackage invalid)
{
return invalid.AsSerializable_Incompatible().Version;
}
return package.VersionString;
}
private static async Task<string> ReadBundleContentAsync(IpcBundleImportRequest request)
{
bool hasContent = !string.IsNullOrWhiteSpace(request.Content);
bool hasPath = !string.IsNullOrWhiteSpace(request.Path);
if (hasContent == hasPath)
{
throw new InvalidOperationException(
"Exactly one of content or path must be supplied when importing a bundle."
);
}
if (hasContent)
{
return request.Content!;
}
return await File.ReadAllTextAsync(request.Path!);
}
private static BundleFormatType ResolveImportFormat(IpcBundleImportRequest request)
{
if (!string.IsNullOrWhiteSpace(request.Format))
{
return ParseFormat(request.Format);
}View on GitHub (pinned to 9b1d7d0eab)
Solutions
- Set exactly one of request.Content or request.Path; leave the other null.
- If importing from a file, set Path and leave Content null.
- If importing inline JSON/YAML/XML, set Content and leave Path null.
- Validate the XOR condition client-side before calling ImportBundleAsync.
Example fix
// before: both fields set (ambiguous)
await IpcBundleApi.ImportBundleAsync(new IpcBundleImportRequest { Content = json, Path = "/tmp/b.ubundle" });
// after: exactly one source
await IpcBundleApi.ImportBundleAsync(new IpcBundleImportRequest { Content = json });
// or
await IpcBundleApi.ImportBundleAsync(new IpcBundleImportRequest { Path = "/tmp/b.ubundle" }); Defensive patterns
Strategy: validation
Validate before calling
bool hasContent = !string.IsNullOrWhiteSpace(request.Content);
bool hasPath = !string.IsNullOrWhiteSpace(request.Path);
if (hasContent == hasPath)
throw new ArgumentException("Provide exactly one of Content or Path."); Type guard
static bool HasExactlyOneBundleSource(IpcBundleImportRequest r)
{
bool c = !string.IsNullOrWhiteSpace(r.Content);
bool p = !string.IsNullOrWhiteSpace(r.Path);
return c ^ p;
} Try / catch
try { await IpcBundleApi.ImportBundleAsync(request); }
catch (InvalidOperationException ex) when (ex.Message.Contains("content or path"))
{ /* client must set exactly one field */ } Prevention
- Set exactly one of Content or Path in IpcBundleImportRequest; null the other.
- Validate the XOR condition client-side before sending.
- Use Content for inline imports and Path for file imports.
When it happens
Trigger: An IpcBundleImportRequest is passed to ImportBundleAsync where both Content and Path are set (ambiguous), or both are null/empty/whitespace (no data). The XOR condition hasContent == hasPath catches both cases: true==true (both set) and false==false (neither set).
Common situations: A client sends both an inline content blob and a file path, expecting the API to pick one. A client sends neither, expecting a file dialog or default. A UI form populates both fields. A serialization issue leaves both fields null when one should have been set.
Related errors
- The backup key is required.
- The bundle format "{format}" is not supported.
- The bundle content could not be parsed.
- Unsupported page \"{page}\". Supported pages: {string.Join("
- The cloud backup \"{key}\" was not found.
AI-assisted analysis of Devolutions/UniGetUI@9b1d7d0eab (2026-08-13).
Data as JSON: /api/errors/05a3c920bd41e288.
Report an issue: GitHub.