{"record":{"id":"b411321cac7f103b","repo":"AvaloniaUI/Avalonia","slug":"the-object-doesn-t-have-an-associated-server-count","errorCode":null,"errorMessage":"The object doesn't have an associated server counterpart","messagePattern":"The object doesn't have an associated server counterpart","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Rendering/Composition/CompositionObject.cs","lineNumber":165,"sourceCode":"                if (animation.Target == null)\n                    throw new ArgumentException(\"Animation Target can't be null\");\n                StopAnimation(animation.Target);\n            }\n            else if (grp is CompositionAnimationGroup group)\n            {\n                foreach (var a in group.Animations)\n                {\n                    if (a.Target == null)\n                        throw new ArgumentException(\"Animation Target can't be null\");\n                    StopAnimation(a.Target);\n                }\n            }\n        }\n\n        protected void RegisterForSerialization()\n        {\n            if (Server == null)\n                throw new InvalidOperationException(\"The object doesn't have an associated server counterpart\");\n            \n            if(_registeredForSerialization)\n                return;\n            _registeredForSerialization = true;\n            Compositor.RegisterForSerialization(this);\n        }\n\n        void ICompositorSerializable.SerializeChanges(Compositor c, BatchStreamWriter writer)\n        {\n            Debug.Assert(c == Compositor);\n            _registeredForSerialization = false;\n            SerializeChangesCore(writer);\n        }\n\n        private protected virtual void SerializeChangesCore(BatchStreamWriter writer)\n        {\n        }\n    }","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Rendering/Composition/CompositionObject.cs#L147-L183","documentation":"The protected RegisterForSerialization refuses to enqueue an object that has no server counterpart (Server == null), because only objects with a real server can be serialized into a commit batch. This is a precondition guard for subclass authors, not a path normal app code should hit.","triggerScenarios":"A CompositionObject subclass calls RegisterForSerialization before its server has been created, or an object type that is inherently server-less (PropertySet/Animation-like) calls it.","commonSituations":"Custom CompositionObject subclasses that forget to create/assign a server in their constructor before triggering serialization; calling RegisterForSerialization on an object whose server failed to allocate.","solutions":["Ensure Server is non-null before calling RegisterForSerialization in any subclass.","Construct the server object in the subclass constructor and pass it to the CompositionObject base ctor.","Do not call RegisterForSerialization on server-less composition objects."],"exampleFix":"// before (subclass)\npublic MyObject(Compositor c) : base(c, null) {}\nvoid OnChanged() => RegisterForSerialization(); // Server null -> throws\n\n// after\npublic MyObject(Compositor c) : base(c, new ServerMyObject(c)) {}\nvoid OnChanged() => RegisterForSerialization();","handlingStrategy":"validation","validationCode":"// In a subclass: only serialize when a server exists.\nif (Server == null) return;\nRegisterForSerialization();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create the server in the subclass constructor and pass it to the CompositionObject base ctor.","Never call RegisterForSerialization on server-less composition objects.","Guard serialization entry points on Server != null."],"tags":["composition","compositor","serialization","subclassing","internal-invariant"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}