dotnet/maui · error · InvalidOperationException
This should never happen, please file a bug
Error message
This should never happen, please file a bug
What it means
In InsertPageBefore, the renderer looks up the 'before' page in PageController.InternalChildren (the NavigationPage's own model-level stack). If IndexOf returns -1, the page isn't in the model stack at all — an invariant violation between the model (NavigationPage.InternalChildren) and the call. The message asks for a bug report because the navigation framework should keep these in sync; a user-facing InsertPageBefore(page, nonStackPage) would surface a different error upstream.
Source
Thrown at src/Compatibility/Core/src/GTK/Renderers/NavigationPageRenderer.cs:404
{
Widget.RemoveFromContainer(target.Container);
}
FinishRemovePage(page, removeFromStack);
}
}
private void InsertPageBefore(Page page, Page before)
{
if (before == null)
throw new ArgumentNullException(nameof(before));
if (page == null)
throw new ArgumentNullException(nameof(page));
int index = PageController.InternalChildren.IndexOf(before);
if (index == -1)
throw new InvalidOperationException("This should never happen, please file a bug");
var items = _currentStack.ToArray();
_currentStack.Clear();
int counter = 0;
foreach (var item in items.Reverse())
{
if (counter == index)
{
_currentStack.Push(new NavigationChildPage(page));
if (Platform.GetRenderer(page) == null)
Platform.SetRenderer(page, Platform.CreateRenderer(page));
}
_currentStack.Push(item);
View on GitHub (pinned to f377ff1c5e)
Solutions
- Serialize navigation mutations (avoid concurrent Push/Pop/InsertPageBefore on the same NavigationPage) so the model stack stays consistent.
- Before calling Navigation.InsertPageBefore(page, before), verify the 'before' page is still on the stack: if (!Navigation.NavigationStack.Contains(before)) return;
- If reproducible, file a bug with the navigation sequence as the message requests — this path indicates a framework invariant breach.
Example fix
// before
Navigation.InsertPageBefore(newPage, targetPage); // targetPage may already be popped
// after
if (Navigation.NavigationStack.Contains(targetPage))
Navigation.InsertPageBefore(newPage, targetPage); Defensive patterns
Strategy: validation
Validate before calling
// Ensure 'before' is still on the model stack before inserting.
if (Navigation.NavigationStack.Contains(before))
Navigation.InsertPageBefore(page, before); Type guard
static bool IsOnStack(Page p) => Navigation.NavigationStack.Contains(p);
Try / catch
try { Navigation.InsertPageBefore(page, before); }
catch (InvalidOperationException ex) when (ex.Message.Contains("never happen"))
{ /* log + skip; indicates stack desync */ } Prevention
- Serialize navigation mutations to avoid re-entrancy.
- Verify the anchor page is still present before inserting.
- Report deterministic reproductions as framework bugs.
When it happens
Trigger: NavigationPage's renderer receives an InsertPageBefore request whose 'before' page is not present in the NavigationPage's InternalChildren. This usually reflects an internal desync rather than a direct API misuse, often triggered by rapid/reentrant navigation or a push/pop race on GTK.
Common situations: Programmatic navigation fired while a previous navigation animation/completion is still in flight. Custom navigation logic that calls InsertPageBefore with a page that was already removed. Shell or custom routers interacting with a NavigationPage on GTK.
Related errors
- Popped page does not appear on top of current navigation sta
- NavigationPage must have a root Page before being used. Eith
- Popped page does not appear on top of current navigation sta
- ParentingViewController parent could not be found. Please fi
- PopToRootAsync is not supported globally on GTK, please use
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/a29d849ed34b4e09.
Report an issue: GitHub.