AvaloniaUI/Avalonia · error · ArgumentException

File path is expected to be an absolute link with "file" or

Error message

File path is expected to be an absolute link with "file" or "content" scheme.

What it means

Thrown by AndroidStorageProvider.TryGetFileFromPathAsync when the supplied Uri is not absolute, or its Scheme is neither "file" nor "content". On Android, Avalonia can only resolve storage items via the file:// or content:// URI schemes that the Storage Access Framework and filesystem understand.

Source

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

    public bool CanPickFolder => OperatingSystem.IsAndroidVersionAtLeast(21);

    public Task<IStorageBookmarkFolder?> OpenFolderBookmarkAsync(string bookmark)
    {
        var uri = DecodeUriFromBookmark(bookmark);
        return Task.FromResult<IStorageBookmarkFolder?>(uri is null ? null : new AndroidStorageFolder(_activity, uri, false));
    }

    public async Task<IStorageFile?> TryGetFileFromPathAsync(Uri filePath)
    {
        if (filePath is null)
        {
            throw new ArgumentNullException(nameof(filePath));
        }

        if (filePath is not { IsAbsoluteUri: true, Scheme: "file" or "content" })
        {
            throw new ArgumentException("File path is expected to be an absolute link with \"file\" or \"content\" scheme.");
        }

        var androidUri = AndroidUri.Parse(filePath.ToString());
        if (androidUri?.Path is not {} androidUriPath)
        {
            return null;
        }

        // About the READ_EXTERNAL_STORAGE permission:
        // https://developer.android.com/reference/android/Manifest.permission#READ_EXTERNAL_STORAGE
        //  - "Starting in API level 33, this permission has no effect."
        //  - "Also starting in API level 19, this permission is not required
        //     to read or write files in your application-specific directories [...]"
        // Consequently, we don't try to check for that permission here anymore.

        var javaFile = new JavaFile(androidUriPath);
        if (javaFile.Exists() && javaFile.IsFile)
        {

View on GitHub (pinned to 11c5427268)

Solutions

  1. Construct the URI explicitly as absolute with the correct scheme: new Uri(filePath, UriKind.Absolute) where filePath starts with file:// or content://.
  2. If you have a bare filesystem path, wrap it: new Uri(new System.IO.FileInfo(path).FullName) or build file:// manually.
  3. Validate Uri.IsAbsoluteUri and Uri.Scheme before calling TryGetFileFromPathAsync and reject/convert unsupported schemes upstream.
  4. For content URIs from intents/pickers, pass them through directly without re-parsing into a different scheme.

Example fix

// before
var file = await provider.TryGetFileFromPathAsync(new Uri("/sdcard/doc.txt"));

// after
var path = System.IO.Path.GetFullPath("/sdcard/doc.txt");
var file = await provider.TryGetFileFromPathAsync(new Uri($"file://{path}"));
Defensive patterns

Strategy: validation

Validate before calling

// validate scheme before calling the provider
if (filePath is not { IsAbsoluteUri: true } || (filePath.Scheme != "file" && filePath.Scheme != "content"))
    throw new ArgumentException("Use an absolute file:// or content:// URI.");
var file = await provider.TryGetFileFromPathAsync(filePath);

Type guard

static bool IsValidAndroidStorageUri(Uri? u) => u is { IsAbsoluteUri: true } && (u.Scheme == "file" || u.Scheme == "content");

Prevention

When it happens

Trigger: Calling TryGetFileFromPathAsync with a relative Uri, or an absolute Uri using an unsupported scheme (e.g. http://, ftp://, custom://, or a bare path string wrapped via new Uri(path) which may produce a relative Uri depending on escaping).

Common situations: Passing a raw filesystem path string instead of a file:// URI; receiving a path from cross-platform code that uses a different scheme; UriKind issues where new Uri(value) defaults to relative for some inputs; sharing a URI from another platform (desktop/iOS) into the Android provider.

Related errors


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