{"record":{"id":"70b3e8b57dcea0c9","repo":"yuliskov/SmartTube","slug":"can-t-create-root-of-surfaceplaybackfragment","errorCode":null,"errorMessage":"Can't create root of SurfacePlaybackFragment","messagePattern":"Can't create root of SurfacePlaybackFragment","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/playback/mod/surface/SurfacePlaybackFragment.java","lineNumber":40,"sourceCode":" * Subclass of {@link PlaybackSupportFragment} that is responsible for providing a {@link SurfaceView}\n * and rendering video.\n */\npublic class SurfacePlaybackFragment extends PlaybackSupportFragment {\n    private SurfaceWrapper mVideoSurfaceWrapper;\n    private AspectRatioFrameLayout mVideoSurfaceRoot;\n    private SubtitleView mLeanbackSubtitles;\n    private int mSubtitlesPadding;\n    private int mBackgroundResId;\n    private float mAspectRatio;\n    private float mPixelRatio = 1.0f;\n    private float mVideoAspectRatio;\n\n    @Override\n    public View onCreateView(\n            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n        ViewGroup root = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState);\n        if (root == null) {\n            throw new IllegalStateException(\"Can't create root of SurfacePlaybackFragment\");\n        }\n        mVideoSurfaceWrapper = (PlayerTweaksData.instance(getContext()).isTextureViewEnabled() ||\n                PlayerData.instance(getContext()).getRotationAngle() != 0) ?\n                new TextureViewWrapper(getContext(), root) : new SurfaceViewWrapper(getContext(), root);\n        mVideoSurfaceRoot = root.findViewById(com.liskovsoft.smartyoutubetv2.tv.R.id.surface_root);\n        mVideoSurfaceRoot.addView(mVideoSurfaceWrapper.getSurfaceView(), 0);\n        mVideoSurfaceRoot.setAspectRatioListener((targetAspectRatio, naturalAspectRatio, aspectRatioMismatch) -> scaleIfNeeded());\n        mLeanbackSubtitles = root.findViewById(com.liskovsoft.smartyoutubetv2.tv.R.id.leanback_subtitles);\n        mSubtitlesPadding = mLeanbackSubtitles.getPaddingLeft();\n        setBackgroundType(PlaybackSupportFragment.BG_LIGHT);\n        return root;\n    }\n\n    /**\n     * Adds {@link SurfaceHolder.Callback} to {@link SurfaceView}.\n     */\n    public void setSurfaceHolderCallback(SurfaceHolder.Callback callback) {\n        if (mVideoSurfaceWrapper != null) {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/yuliskov/SmartTube/blob/3de8d90593e0166f012ca18cc3c7ba45bfd68ac4/smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/playback/mod/surface/SurfacePlaybackFragment.java#L22-L58","documentation":"SurfacePlaybackFragment.onCreateView takes super.onCreateView(...) (the leanback PlaybackSupportFragment view inflation) and casts it to ViewGroup; if the base returns null it throws IllegalStateException('Can't create root of SurfacePlaybackFragment') to fail fast before root.findViewById(surface_root/leanback_subtitles) would NPE. A null super view means the base playback fragment's layout never inflated.","triggerScenarios":"The androidx.leanback base fragment's onCreateView returning null — typically a leanback version change in layout inflation, a subclass between SurfacePlaybackFragment and the base overriding onCreateView and returning null, or inflation failing silently on a null container during certain restore paths.","commonSituations":"Upgrading androidx.leanback to a version where PlaybackSupportFragment/VideoSupportFragment view creation changed; mod layers or forks overriding onCreateView without returning the inflated root; layouts missing the ids the code then uses (surface_root, leanback_subtitles).","solutions":["Check every intermediate override of onCreateView in your subclass chain — each must return the inflated view, never null.","Align/pin the androidx.leanback dependency to a version compatible with this code (the base is expected to inflate a non-null video fragment layout).","Verify the layout actually inflated (no silently swallowed InflateException) by logging super.onCreateView's result before the cast.","If you maintain the code, replace the throw with a fallback inflation of a layout containing surface_root and leanback_subtitles."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// in your subclass chain, make sure onCreateView never returns null\n@Override\npublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n    View root = super.onCreateView(inflater, container, savedInstanceState);\n    if (root == null) {\n        // base failed to inflate — provide a layout with surface_root + leanback_subtitles\n        root = inflater.inflate(R.layout.surface_playback_fragment, container, false);\n    }\n    return root;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Any override of onCreateView between your fragment and the leanback base must return the inflated view.","Pin androidx.leanback to a version this code was built against; retest playback after upgrades.","Confirm the expected ids (surface_root, leanback_subtitles) exist in the inflated layout."],"tags":["android","android-tv","fragment","view-inflation","leanback","playback"],"backgroundTag":"null-root-view","analyzedSha":"3de8d90593e0166f012ca18cc3c7ba45bfd68ac4","analyzedAt":"2026-08-22T09:19:26.383Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}