dotnet/maui · error · InvalidOperationException
AppLinkEntry Thumbnail must be set to a valid source
Error message
AppLinkEntry Thumbnail must be set to a valid source
What it means
When building a CSSearchableItemAttributeSet for Spotlight indexing, iOSAppLinks optionally attaches a thumbnail image. If the AppLinkEntry.Thumbnail ImageSource is non-null but GetNativeImageAsync() resolves to a null UIImage (the source could not be loaded/decoded), the code throws InvalidOperationException because attaching a null thumbnail would corrupt the Spotlight entry.
Source
Thrown at src/Compatibility/Core/src/iOS/iOSAppLinks.cs:118
static async Task<CSSearchableItemAttributeSet> GetAttributeSet(IAppLinkEntry deepLinkUri, string contentType, string id)
{
#pragma warning disable CA1416, CA1422 // TODO: 'CSSearchableItemAttributeSet' is unsupported on: 'ios' 14.0 and later
var searchableAttributeSet = new CSSearchableItemAttributeSet(contentType)
{
RelatedUniqueIdentifier = id,
Title = deepLinkUri.Title,
ContentDescription = deepLinkUri.Description,
Url = new NSUrl(deepLinkUri.AppLinkUri.ToString())
};
#pragma warning restore CA1416, CA1422
if (deepLinkUri.Thumbnail != null)
{
using (var uiimage = await deepLinkUri.Thumbnail.GetNativeImageAsync())
{
if (uiimage == null)
throw new InvalidOperationException("AppLinkEntry Thumbnail must be set to a valid source");
searchableAttributeSet.ThumbnailData = uiimage.AsPNG();
}
}
return searchableAttributeSet;
}
static NSMutableDictionary GetUserInfoForActivity(IAppLinkEntry deepLinkUri)
{
//this info will only appear if not from a spotlight search
var info = new NSMutableDictionary();
info.Add(new NSString("link"), new NSString(deepLinkUri.AppLinkUri.ToString()));
foreach (var item in deepLinkUri.KeyValues)
info.Add(new NSString(item.Key), new NSString(item.Value));
return info;
}
View on GitHub (pinned to f377ff1c5e)
Solutions
- Verify the thumbnail ImageSource resolves to a real, decodable image before registering the link — test GetNativeImageAsync separately.
- For FileImageSource, confirm the file exists in the app bundle with `File.Exists(imageSource.File)`.
- For UriImageSource, validate the URL is reachable and returns image content before passing it as a Thumbnail.
- If the thumbnail is optional, catch the exception and re-register without a Thumbnail rather than failing the whole registration.
Example fix
// before
entry.Thumbnail = ImageSource.FromFile("missing_icon.png");
Application.Current.AppLinks.RegisterLink(entry);
// after
var thumbPath = "icon.png";
if (File.Exists(thumbPath))
entry.Thumbnail = ImageSource.FromFile(thumbPath);
Application.Current.AppLinks.RegisterLink(entry); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate thumbnail source before registration
if (entry.Thumbnail is FileImageSource fis && !File.Exists(fis.File))
entry.Thumbnail = null; // drop invalid thumbnail
if (entry.Thumbnail is UriImageSource uis && !Uri.IsWellFormedUriString(uis.Uri?.ToString() ?? "", UriKind.Absolute))
entry.Thumbnail = null;
Application.Current.AppLinks.RegisterLink(entry); Try / catch
try
{
Application.Current.AppLinks.RegisterLink(entry);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Thumbnail"))
{
// Retry without a thumbnail
entry.Thumbnail = null;
Application.Current.AppLinks.RegisterLink(entry);
} Prevention
- Test FileImageSource paths against the app bundle before using them as thumbnails.
- Validate remote thumbnail URLs return image content before indexing.
- Treat thumbnails as optional — wrap registration in try-catch and retry without the thumbnail.
When it happens
Trigger: An AppLinkEntry with Thumbnail set to a FileImageSource pointing to a missing file, a UriImageSource pointing to a broken/unreachable URL, or a StreamImageSource that yields an empty or undecodable stream. The Thumbnail property is non-null so the code enters the loading block, but GetNativeImageAsync returns null.
Common situations: Bundled asset paths that changed between versions. Remote thumbnail URLs that 404 or return non-image content. StreamImageSource from a disposed or empty stream. Platform-specific asset naming mismatches (e.g., missing @2x suffix or wrong extension).
Related errors
- AppLinkUri
- uri
- Invalid Uri
- Can't start BlazorWebView without native web view instance.
- Unable to find the required services. Please add all the req
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/0a4749bb964cbb35.
Report an issue: GitHub.