AvaloniaUI/Avalonia · error · Exception

result.GetStringExtra("error")

Error message

result.GetStringExtra("error")

What it means

Thrown after a storage picker Activity returns when the result Intent carries an extra keyed "error" (result.HasExtra("error") == true). Avalonia re-throws the picker provider's error string verbatim as a generic Exception. The actual message is whatever the document/picker provider placed in the "error" extra (security errors, provider unavailable, picker canceled with error, etc.).

Source

Thrown at src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs:261

            {
                for (var i = 0; i < clipData.ItemCount; i++)
                {
                    var uri = clipData.GetItemAt(i)?.Uri;
                    if (uri != null)
                    {
                        resultList.Add(uri);
                    }
                }
            }
            else if (result.Data is { } uri)
            {
                resultList.Add(uri);
            }
        }

        if (result?.HasExtra("error") == true)
        {
            throw new Exception(result.GetStringExtra("error"));
        }

        return resultList;

        void OnActivityResult(int requestCode, Result resultCode, Intent? data)
        {
            if (currentRequestCode != requestCode)
            {
                return;
            }

            mainActivity.ActivityResult -= OnActivityResult;

            _ = tcs.TrySetResult(resultCode == Result.Ok ? data : null);
        }
    }

    private static Intent TryAddExtraInitialUri(Intent intent, IStorageFolder? folder)

View on GitHub (pinned to 11c5427268)

Solutions

  1. Wrap picker calls (OpenFilePicker, SaveFilePicker, OpenFolderPicker) in try/catch and surface the embedded error message to the user.
  2. Inspect the exception's Message (it is the provider's error string) to decide whether to retry or guide the user.
  3. Verify storage permissions and SAF access before invoking the picker; if the error is permission-related, request access.
  4. On repeated failures on a specific device/OEM, offer a fallback (e.g. system file chooser via ACTION_OPEN_DOCUMENT).

Example fix

// before
var files = await storageProvider.OpenFilePickerAsync(options);

// after
try
{
    var files = await storageProvider.OpenFilePickerAsync(options);
}
catch (Exception ex) when (ex.Message != null)
{
    await ShowUser($"Picker error: {ex.Message}");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// no pre-check is possible — the error comes from the picker result extra.
// ensure permissions are in place before launching to reduce error likelihood.
if (activity is not IActivityResultHandler) throw new InvalidOperationException("Activity must be an IActivityResultHandler");

Try / catch

try { return await storageProvider.OpenFilePickerAsync(options); }
catch (Exception ex) { await ShowUser($"Picker error: {ex.Message}"); return Array.Empty<IStorageFile>(); }

Prevention

When it happens

Trigger: A SAF/document picker returns an Intent whose extras include "error". The content is provider-specific: could be a permission denial, an unsupported action, an OEM picker bug, or the picker failing to produce a URI.

Common situations: OEM picker returning an error extra instead of a null result; permissions issues on scoped storage; provider (cloud/office) that signals errors via extras; edge cases on specific Android versions where the picker returns both no URI and an error string.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/589d9cdb77528c7f. Report an issue: GitHub.