AvaloniaUI/Avalonia · error · InvalidOperationException

{o.GetType()} is not compatible with composition

Error message

{o.GetType()} is not compatible with composition

What it means

ServerResourceHelperExtensions.GetServer maps a brush/pen/geometry/transform to its server form; it accepts immutable variants and ICompositionRenderResource, and otherwise calls ThrowNotCompatible with the type name. The helper runs whenever composition drawing resolves a non-immutable resource to a server object on a given compositor.

Source

Thrown at src/Avalonia.Base/Rendering/Composition/Drawing/ServerResourceHelperExtensions.cs:51

    }

    public static IPen? GetServer(this IPen? pen, Compositor? compositor)
    {
        if (compositor == null)
            return pen;
        if (pen == null)
            return null;
        if (pen is ImmutablePen immutable)
            return immutable;
        if (pen is ICompositionRenderResource<IPen> resource)
            return resource.GetForCompositor(compositor);
        ThrowNotCompatible(pen);
        return null;
    }

    [MethodImpl(MethodImplOptions.NoInlining), DoesNotReturn]
    static void ThrowNotCompatible(object o) =>
        throw new InvalidOperationException(o.GetType() + " is not compatible with composition");

    [MethodImpl(MethodImplOptions.NoInlining), DoesNotReturn]
    static void ThrowForeignCompositor(CompositionObject o) =>
        throw new InvalidOperationException(o.GetType() + " belongs to a different compositor");
    
    public static ITransform? GetServer(this ITransform? transform, Compositor? compositor)
    {
        if (compositor == null)
            return transform;
        if (transform == null)
            return null;
        if (transform is ImmutableTransform immutable)
            return immutable;
        if (transform is ICompositionRenderResource<ITransform> resource)
            resource.GetForCompositor(compositor);
        return new ImmutableTransform(transform.Value);
    }

View on GitHub (pinned to 11c5427268)

Solutions

  1. Use immutable variants or composition-backed resources (implement ICompositionRenderResource) for composition rendering.
  2. Wrap custom brushes/pens in their immutable equivalents before handing them to composition drawing.
  3. Implement ICompositionRenderResource on custom resource types so GetServer can resolve them.

Example fix

// before
ctx.DrawLine(myCustomPen, p1, p2); // custom pen not composition/immutable -> throws

// after
var pen = new ImmutablePen(new ImmutableSolidColorBrush(color, 1), thickness);
ctx.DrawLine(pen, p1, p2);
Defensive patterns

Strategy: type-guard

Validate before calling

static bool IsCompositionCompatible(object? r) =>
    r is null or IImmutableBrush or ImmutablePen or ImmutableTransform or ICompositionRenderResource;

Type guard

static bool IsCompositionOrImmutable(object? r) =>
    r is ICompositionRenderResource or IImmutableBrush or ImmutablePen or ImmutableTransform;

Prevention

When it happens

Trigger: Passing a brush, pen, geometry, or transform to composition drawing that is neither immutable (IImmutableBrush/ImmutablePen/ImmutableTransform) nor an ICompositionRenderResource, while a compositor is in use.

Common situations: Using a custom mutable IBrush/IPen/Geometry that does not implement ICompositionRenderResource with a composition render path; third-party media types that are not composition-aware.

Related errors


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