AvaloniaUI/Avalonia · error · InvalidOperationException
There is no server-side counterpart for this object
Error message
There is no server-side counterpart for this object
What it means
Thrown by ICompositorSerializable.TryGetServer when a CompositionObject that reached the commit-batch serialization queue has no server-side counterpart (Server == null). During every commit, Compositor.CommitCore walks its serialization queue (Compositor.cs:138) and asks each object for its server; some types (CompositionAnimation, CompositionPropertySet) are intentionally built with a null server because they serialize via snapshots, so they must never be queued directly.
Source
Thrown at src/Avalonia.Base/Rendering/Composition/CompositionObject.cs:48
/// <summary>
/// The associated Compositor
/// </summary>
public Compositor Compositor { get; }
SimpleServerObject ICompositorSerializable.TryGetServer(Compositor c)
{
Debug.Assert(c == Compositor);
return Server ?? ThrowInvalidOperation();
}
internal SimpleServerObject? Server { get; }
public bool IsDisposed { get; private set; }
private bool _registeredForSerialization;
[MethodImpl(MethodImplOptions.NoInlining)]
private static SimpleServerObject ThrowInvalidOperation() =>
throw new InvalidOperationException("There is no server-side counterpart for this object");
protected internal void Dispose()
{
if (!IsDisposed && Server != null)
Compositor.DisposeOnNextBatch(Server);
IsDisposed = true;
}
/// <summary>
/// Connects an animation with the specified property of the object and starts the animation.
/// </summary>
public void StartAnimation(string propertyName, CompositionAnimation animation)
=> StartAnimation(propertyName, animation, null);
internal virtual void StartAnimation(string propertyName, CompositionAnimation animation, ExpressionVariant? finalValue)
{
throw new ArgumentException("Unknown property " + propertyName);
}View on GitHub (pinned to 11c5427268)
Solutions
- Do not register CompositionAnimation / CompositionPropertySet / base CompositionObject instances for serialization yourself; let the Compositor own the queue.
- Reference PropertySets/animations indirectly via CompositionAnimation.SetReferenceParameter so they serialize through the animation's snapshot path.
- If you subclass CompositionObject, supply a real SimpleServerObject to the base ctor so Server is non-null.
- Never reuse a composition object after Dispose(); recreate it from the Compositor.
Example fix
// before
compositor.RegisterForSerialization(myPropertySet); // PropertySet has Server == null
// after
// reference it through an animation instead
anim.SetReferenceParameter("mySet", myPropertySet); Defensive patterns
Strategy: validation
Validate before calling
// Only register server-backed objects for serialization; never PropertySets/animations directly.
if (obj is CompositionAnimation || obj is CompositionPropertySet)
return; // these have no Server and serialize via snapshots
compositor.RegisterForSerialization(obj); Type guard
static bool HasServerCounterpart(CompositionObject o) => !o.IsDisposed;
Prevention
- Never call Compositor.RegisterForSerialization on CompositionAnimation or CompositionPropertySet.
- Reference PropertySets/animations through CompositionAnimation.SetReferenceParameter so they serialize via the snapshot path.
- Do not reuse composition objects after Dispose(); recreate them from the Compositor.
When it happens
Trigger: An object with Server == null (a bare CompositionObject, a CompositionAnimation, or a CompositionPropertySet) is handed to Compositor.RegisterForSerialization and survives to the next CommitCore, so TryGetServer falls into ThrowInvalidOperation.
Common situations: Calling RegisterForSerialization manually on a PropertySet/animation, reusing a composition object across commit boundaries after its server was torn down, or writing a custom CompositionObject subclass that does not pass a server to the base constructor.
Related errors
- The object doesn't have an associated server counterpart
- This resource doesn't exist on that compositor
- {o.GetType()} belongs to a different compositor
- Composition visuals belong to different compositor instances
- Android backend wasn't initialized. Make sure .UseAndroid()
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/3297698020c3edbe.
Report an issue: GitHub.