{"record":{"id":"182ca8089692a486","repo":"AvaloniaUI/Avalonia","slug":"toplevel-internalview-was-not-expected-to-be-null","errorCode":null,"errorMessage":"TopLevel.InternalView was not expected to be null.","messagePattern":"TopLevel\\.InternalView was not expected to be null\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs","lineNumber":17,"sourceCode":"﻿using System;\nusing Avalonia.Platform.Surfaces;\nusing Avalonia.Platform;\n\nnamespace Avalonia.Android.Platform.SkiaPlatform\n{\n    internal sealed class FramebufferManager : IFramebufferPlatformSurface\n    {\n        private readonly TopLevelImpl _topLevel;\n\n        public FramebufferManager(TopLevelImpl topLevel)\n        {\n            _topLevel = topLevel;\n        }\n\n        public ILockedFramebuffer Lock() => new AndroidFramebuffer(\n            _topLevel.InternalView ?? throw new InvalidOperationException(\"TopLevel.InternalView was not expected to be null.\"),\n            _topLevel.RenderScaling);\n\n        public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock);\n    }\n}\n","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs#L1-L23","documentation":"Thrown by FramebufferManager.Lock() when _topLevel.InternalView (the InvalidationAwareSurfaceView) is null. The framebuffer path requires a live surface view; a null means the TopLevelImpl has been disposed or its SurfaceViewImpl was never/ no longer instantiated when a frame was requested.","triggerScenarios":"Calling FramebufferManager.Lock() after TopLevelImpl has disposed its _view, or during teardown of an embedded AvaloniaView while a pending render callback still fires. Occurs when the compositor/scheduler still holds a reference to the framebuffer surface after the underlying view was torn down.","commonSituations":"Disposing an AvaloniaView (Activity finish, fragment destruction) while a render timer or animation is still ticking; hot-reload scenarios; rapid Activity recreation in config changes where the old TopLevelImpl receives a late render request.","solutions":["Dispose the TopLevel/TopLevelImpl fully and unsubscribe all render timers before the view is destroyed so no late Lock() call occurs.","If you maintain a custom render loop, null-check InternalView before requesting a frame and bail out silently when it is null.","Ensure the host Activity/Fragment lifecycle tears down the Avalonia view in onStop/onDestroy before any background task can trigger rendering.","Report upstream if this fires under normal lifecycle — it indicates a missing render-scheduler detach on disposal."],"exampleFix":"// before\n// render callback fires unconditionally\n compositor.RequestCompositionPaint();\n\n// after — guard the render request against a torn-down view\nif (_topLevelImpl.InternalView is not null)\n    compositor.RequestCompositionPaint();","handlingStrategy":"validation","validationCode":"// before requesting a frame, ensure the TopLevel still has its view\nif (_topLevelImpl.InternalView is null) return;","typeGuard":"static bool IsTopLevelAlive(TopLevelImpl? impl) => impl?.InternalView is not null;","tryCatchPattern":"// prefer preventing the call; if you cannot, isolate the render tick:\ntry { compositor.RequestPaint(); }\ncatch (InvalidOperationException) when (topLevel.InternalView is null) { /* shutting down */ }","preventionTips":["Fully dispose TopLevel/TopLevelImpl and stop render timers before destroying the host view.","Null-check InternalView in custom render loops before each frame.","Tear down the Avalonia view in the host Activity/Fragment lifecycle (onStop/onDestroy).","Avoid scheduling renders from background tasks that outlive the view."],"tags":["android","rendering","lifecycle","disposal","framebuffer"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}