YoKeyword/Fragmentation · error · IllegalStateException
Can't find container, please call loadRootFragment() first!
Error message
Can't find container, please call loadRootFragment() first!
What it means
getTopFragmentForStart determines which container a new fragment goes into based on the 'from' fragment's containerId. If the from fragment has mContainerId == 0 and was never added via a viewpager adapter (tag not starting with 'android:switcher:'), the library cannot locate a container and throws an IllegalStateException.
Solutions
- Load the fragment with loadRootFragment()/start() so the containerId is bound before navigating from it.
- If the fragment is inside a viewpager, add it via the library's FragmentPagerAdapter so the 'android:switcher:' tag is set.
- Ensure the from fragment was added to a container with a valid container id (bind via SupportFragmentDelegate.mContainerId).
Example fix
// before getFragmentManager().beginTransaction().add(R.id.fl, myFragment, "mine").commit(); myFragment.start(new DetailFragment()); // after loadRootFragment(R.id.fl, myFragment); // later myFragment.start(new DetailFragment());
Defensive patterns
Strategy: validation
Validate before calling
if (fromFragment.getSupportDelegate().mContainerId == 0 && (fromFragment.getTag() == null || !fromFragment.getTag().startsWith("android:switcher:"))) {
// load via library APIs before starting navigation
} Prevention
- Always add fragments via loadRootFragment()/start(), never raw FragmentTransaction.
- Use the library's FragmentPagerAdapter for viewpager-hosted fragments.
- Ensure every navigating fragment has a bound containerId.
When it happens
Trigger: Calling start()/startForResult() from a fragment that was never added through loadRootFragment or a viewpager, so its containerId is still 0 and its tag is a custom/unknown tag.
Common situations: Manually adding a SupportFragment with a plain FragmentTransaction then starting navigation from it; fragments created programmatically and added with custom tags; nested fragments not loaded via the library APIs.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- There is no Fragment in the FragmentManager, maybe you need…
- Must extends Fragment
- not attach!
- Fragment has not been attached to Activity!
- Must extends FragmentActivity/AppCompatActivity
AI-assisted analysis of YoKeyword/Fragmentation@0394930a3e (2026-09-10).
Data as JSON: /api/errors/293c3c59719aeba2.
Report an issue: GitHub.
Appendix: source
Thrown at fragmentation_core/src/main/java/me/yokeyword/fragmentation/TransactionDelegate.java:388
if (transactionRecord.sharedElementList != null) {
sharedElementList = transactionRecord.sharedElementList;
}
}
if (handleLaunchMode(fm, from, to, toFragmentTag, launchMode)) return;
start(fm, from, to, toFragmentTag, dontAddToBackStack, sharedElementList, false, type);
}
private ISupportFragment getTopFragmentForStart(ISupportFragment from, FragmentManager fm) {
ISupportFragment top;
if (from == null) {
top = SupportHelper.getTopFragment(fm);
} else {
if (from.getSupportDelegate().mContainerId == 0) {
Fragment fromF = (Fragment) from;
if (fromF.getTag() != null && !fromF.getTag().startsWith("android:switcher:")) {
throw new IllegalStateException("Can't find container, please call loadRootFragment() first!");
}
}
top = SupportHelper.getTopFragment(fm, from.getSupportDelegate().mContainerId);
}
return top;
}
private void start(FragmentManager fm, final ISupportFragment from, ISupportFragment to, String toFragmentTag,
boolean dontAddToBackStack, ArrayList<TransactionRecord.SharedElement> sharedElementList, boolean allowRootFragmentAnim, int type) {
FragmentTransaction ft = fm.beginTransaction();
boolean addMode = (type == TYPE_ADD || type == TYPE_ADD_RESULT || type == TYPE_ADD_WITHOUT_HIDE || type == TYPE_ADD_RESULT_WITHOUT_HIDE);
Fragment fromF = (Fragment) from;
Fragment toF = (Fragment) to;
Bundle args = getArguments(toF);
args.putBoolean(FRAGMENTATION_ARG_REPLACE, !addMode);
if (sharedElementList == null) {
if (addMode) { // Replace mode forbidden animation, the replace animations exist overlapping Bug on support-v4.View on GitHub (pinned to 0394930a3e)