AvaloniaUI/Avalonia · error · InvalidOperationException

Main activity must implement IActivityResultHandler interfac

Error message

Main activity must implement IActivityResultHandler interface.

What it means

PlatformSupport.CheckPermission is an extension on Activity that launches the runtime permission request flow, which needs the activity to route OnRequestPermissionsResult callbacks. It throws InvalidOperationException when the activity is not an IActivityResultHandler (Avalonia's main activity contract). Without it, the permission result cannot be delivered.

Source

Thrown at src/Android/Avalonia.Android/Platform/PlatformSupport.cs:19

using System;
using System.Linq;
using System.Threading.Tasks;
using Android.App;
using Android.Content.PM;

namespace Avalonia.Android.Platform;

internal static class PlatformSupport
{
    private static int s_lastRequestCode = 20000;

    public static int GetNextRequestCode() => s_lastRequestCode++;

    public static async Task<bool> CheckPermission(this Activity activity, string permission)
    {
        if (activity is not IActivityResultHandler mainActivity)
        {
            throw new InvalidOperationException("Main activity must implement IActivityResultHandler interface.");
        }

        if (!OperatingSystem.IsAndroidVersionAtLeast(23))
        {
            return true;
        }

        if (activity.CheckSelfPermission(permission) == Permission.Granted)
        {
            return true;
        }
        
        var currentRequestCode = GetNextRequestCode();
        var tcs = new TaskCompletionSource<bool>();
        mainActivity.RequestPermissionsResult += RequestPermissionsResult;
        activity.RequestPermissions(new [] { permission }, currentRequestCode);

        return await tcs.Task;

View on GitHub (pinned to 11c5427268)

Solutions

  1. Call CheckPermission from the Avalonia main activity (AvaloniaMainActivity / AvaloniaActivity), which implements IActivityResultHandler.
  2. If using a custom Activity, implement IActivityResultHandler and forward OnRequestActivityResult to RequestPermissionsResult.
  3. Resolve the activity to the main activity (e.g. via the activatable lifetime) before calling CheckPermission.
  4. For Fragments, route through the host main activity rather than the fragment's Activity.

Example fix

// before
if (activity is not IActivityResultHandler mainActivity)
    throw new InvalidOperationException("Main activity must implement IActivityResultHandler interface.");

// after (use the main activity from the activatable lifetime, with a clearer message)
var handler = (activity as IActivityResultHandler)
    ?? (Avalonia.Application.Current?.TryGetFeature<IActivatableLifetime>() as AndroidActivatableLifetime)?.CurrentMainActivity as IActivityResultHandler
    ?? throw new InvalidOperationException(
        $"Activity '{activity.GetType().FullName}' must implement IActivityResultHandler; call CheckPermission from the Avalonia main activity.");
Defensive patterns

Strategy: type-guard

Validate before calling

// call from the main activity, not an arbitrary activity
if (activity is not IActivityResultHandler) return; // or route to the main activity

Type guard

static bool CanRequest(Activity a) => a is IActivityResultHandler;

Try / catch

// guard the caller; ensure CheckPermission runs against the Avalonia main activity.

Prevention

When it happens

Trigger: Calling activity.CheckPermission(...) on an Activity that is not the Avalonia main activity (i.e. does not implement IActivityResultHandler). The permission request needs IActivityResultHandler.OnRequestPermissionsResult wiring that only the main activity provides.

Common situations: Requesting permissions from a secondary Activity, a Fragment context cast to Activity, or a custom Activity that did not extend AvaloniaMainActivity; integrating permission requests before wiring the activity-result handler.

Related errors


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