PrismLibrary/Prism · error · NavigationException

Invalid Tab Name

Error message

Invalid Tab Name: {tabName}

What it means

SelectTabAsync parses the tabName using '|' as a separator; exactly one part means a direct tab and two parts mean a NavigationPage child ('root|leaf'). If the string contains more than one '|' (or is otherwise malformed so parts.Length is neither 1 nor 2), the method throws NavigationException('Invalid Tab Name: {tabName}').

Solutions

  1. Pass a name with at most one '|' (e.g. "TabName" or "NavPage|ChildPage").
  2. Strip the TabbedPage prefix from a deep-link URI and pass only the tab segment.
  3. Validate/split the name yourself before calling, and throw a clearer app-level error for malformed input.
  4. Use NavigateAsync with the full URI if you actually need multi-segment navigation.

Example fix

// before
await _navigationService.SelectTabAsync("TabbedPage/NavPage|Child|Extra");
// after
await _navigationService.SelectTabAsync("NavPage|Child");
Defensive patterns

Strategy: validation

Validate before calling

var parts = tabName.Split('|');
if (parts.Length is not (1 or 2))
    throw new ArgumentException($"Tab name must be 'tab' or 'navRoot|leaf': {tabName}");

Type guard

bool IsValidTabName(string tabName) =>
    !string.IsNullOrWhiteSpace(tabName) && tabName.Split('|').Length is 1 or 2;

Try / catch

try { await _navigationService.SelectTabAsync(tabName); }
catch (NavigationException ex) when (ex.Message.StartsWith("Invalid Tab Name"))
{ /* fix name or fall back to NavigateAsync */ }

Prevention

When it happens

Trigger: Passing a tab name with two or more '|' separators, e.g. "A|B|C"; passing a fully qualified URI by mistake where SelectTabAsync expects the short tab-name syntax.

Common situations: Copy-pasting a deep-link URI ('TabbedPage/A|B') into SelectTabAsync instead of just the tab segment; building names dynamically and joining too many segments; confusion between NavigateAsync URI syntax and SelectTabAsync name syntax.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15). Data as JSON: /api/errors/6a42e61eff568384. Report an issue: GitHub.

Appendix: source

Thrown at src/Maui/Prism.Maui/Navigation/PageNavigationService.cs:397

            {
                var tabRegistration = Registry.Registrations.FirstOrDefault(x => x.Name == tabName);
                selectedChild = tabbedPage.Children.FirstOrDefault(x =>
                    ViewModelLocator.GetNavigationName(x) == tabName
                    || (x is NavigationPage navPage && ViewModelLocator.GetNavigationName(navPage.RootPage) == tabName)
                    || (tabRegistration is not null && x is NavigationPage np && IsPage(np.RootPage, tabRegistration, tabName))
                    || (tabRegistration is not null && IsPage(x, tabRegistration, tabName)));
            }
            else if (parts.Length == 2)
            {
                var rootRegistration = Registry.Registrations.FirstOrDefault(x => x.Name == parts[0]);
                var leafRegistration = Registry.Registrations.FirstOrDefault(x => x.Name == parts[1]);
                selectedChild = tabbedPage.Children.FirstOrDefault(x =>
                    x is NavigationPage navPage
                    && (ViewModelLocator.GetNavigationName(navPage) == parts[0] || (rootRegistration is not null && IsPage(navPage, rootRegistration, parts[0])))
                    && (ViewModelLocator.GetNavigationName(navPage.RootPage) == parts[1] || (leafRegistration is not null && IsPage(navPage.RootPage, leafRegistration, parts[1]))));
            }
            else
                throw new NavigationException($"Invalid Tab Name: {tabName}");

            if (selectedChild is null)
                throw new NavigationException($"No Tab found with the Name: {tabName}");

            var navigatedFromPage = _pageAccessor.Page;
            if (!await MvvmHelpers.CanNavigateAsync(navigatedFromPage, parameters))
                throw new NavigationException(NavigationException.IConfirmNavigationReturnedFalse, navigatedFromPage);

            var navigatedToTarget = selectedChild is NavigationPage navPage ? navPage.CurrentPage : selectedChild;
            if (uri is not null)
            {
                if (uri.IsAbsoluteUri)
                {
                    throw new NavigationException("Cannot process an absolute Navigation Uri when navigating within a specified Tab");
                }

                var navigationSegments = UriParsingHelper.GetUriSegments(uri);
                await ProcessNavigation(navigatedToTarget, navigationSegments, parameters, null, null);

View on GitHub (pinned to 358118cd64)