Skip to content

[go_router] path parameters regex can't use grouping #117307

Closed
flutter/packages
#12571

Description

@TheManuz

Steps to Reproduce

Declare a GoRoute with a path like this:

/details/:id((FOO|BAR)[0-9a-zA-Z]{10})

Expected results:
The following values for id should both match:
FOO1234567890
BAR1234567890

Actual results:
The route path doesn't match, and the app goes to the "Page not found" route.

Code sample
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

void main() => runApp(const MyApp());

/// The route configuration.
final GoRouter _router = GoRouter(
  debugLogDiagnostics: true,
  routes: <RouteBase>[
    GoRoute(
      path: '/',
      builder: (_, __) => const HomeScreen(),
    ),
    GoRoute(
      path: '/details/:id((FOO|BAR)[0-9a-zA-Z]{10})',
      builder: (_, state) => DetailsScreen(state.params["id"]!),
    ),
  ],
);

/// The main app.
class MyApp extends StatelessWidget {
  /// Constructs a [MyApp]
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _router,
    );
  }
}

/// The home screen
class HomeScreen extends StatelessWidget {
  /// Constructs a [HomeScreen]
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home Screen')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () => context.push('/details/FOO1234567890'),
              child: const Text('FOO1234567890'),
            ),
            ElevatedButton(
              onPressed: () => context.push('/details/BAR1234567890'),
              child: const Text('BAR1234567890'),
            ),
          ],
        ),
      ),
    );
  }
}

/// The details screen
class DetailsScreen extends StatelessWidget {
  final String id;

  /// Constructs a [DetailsScreen]
  const DetailsScreen(this.id, {super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Details Screen')),
      body: Center(
        child: Text("Id is:\n $id"),
      ),
    );
  }
}
Logs
[GoRouter] Full paths for routes:
             => /
             => /details/:id((FOO|BAR)[0-9a-zA-Z]{10})
[GoRouter] setting initial location null
[GoRouter] Using MaterialApp configuration
[GoRouter] pushing /details/FOO1234567890
[GoRouter] No initial matches: /details/FOO1234567890
[GoRouter] going to /
[GoRouter] pushing /details/BAR1234567890
[GoRouter] No initial matches: /details/BAR1234567890
flutter analyze
Analyzing bug...                                                        
No issues found! (ran in 1.2s)
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.3.9, on macOS 13.0 22A380 darwin-arm, locale it-IT)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.3)
[✓] VS Code (version 1.74.0)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

• No issues found!

Activity

  1. added
    in triagePresently being triaged by the triage team
    on Dec 19, 2022
  2. exaby73 commented on Dec 19, 2022

    @exaby73
    Member

    Triage report

    I can reproduce this issue with go_router: 5.2.4. Experimenting with different ways of writing the regex with groups, doesn't work. Removing the group with something like [a-zA-Z0-9]{13} works.

    Code Sample (Same as OP)
     import 'package:flutter/material.dart';
    import 'package:go_router/go_router.dart';
    
    void main() => runApp(const MyApp());
    
    /// The route configuration.
    final GoRouter _router = GoRouter(
      debugLogDiagnostics: true,
      routes: <RouteBase>[
        GoRoute(
          path: '/',
          builder: (_, __) => const HomeScreen(),
        ),
        GoRoute(
          path: '/details/:id((FOO|BAR)[0-9a-zA-Z]{10})',
          builder: (_, state) => DetailsScreen(state.params["id"]!),
        ),
      ],
    );
    
    /// The main app.
    class MyApp extends StatelessWidget {
      /// Constructs a [MyApp]
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp.router(
          routerConfig: _router,
        );
      }
    }
    
    /// The home screen
    class HomeScreen extends StatelessWidget {
      /// Constructs a [HomeScreen]
      const HomeScreen({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Home Screen')),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                ElevatedButton(
                  onPressed: () => context.push('/details/FOO1234567890'),
                  child: const Text('FOO1234567890'),
                ),
                ElevatedButton(
                  onPressed: () => context.push('/details/BAR1234567890'),
                  child: const Text('BAR1234567890'),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    /// The details screen
    class DetailsScreen extends StatelessWidget {
      final String id;
    
      /// Constructs a [DetailsScreen]
      const DetailsScreen(this.id, {super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Details Screen')),
          body: Center(
            child: Text("Id is:\n $id"),
          ),
        );
      }
    }
  3. added
    packageflutter/packages repository. See also p: labels.
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    and removed
    in triagePresently being triaged by the triage team
    on Dec 19, 2022
  4. added
    P2Important issues not at the top of the work list
    on Jan 10, 2023
  5. MaximeRougieux commented on Aug 24, 2026

    @MaximeRougieux

    In addition to what you are mentioning, it seems the Regexp parsing cannot handle any internal parenthesis, so it excludes patterns like /details/:id((?!FOO|BAR)[0-9a-zA-Z]{10}) which should match BAZ0123456789 but not FOO0123456789, instead the pattern is read literally

    I have opened a PR to fix these issues: flutter/packages#12571

  6. github-actions commented on Nov 13, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  7. locked as resolved and limited conversation to collaborators on Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listfound in release: 3.3Found to occur in 3.3found in release: 3.7Found to occur in 3.7has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: go_routerThe go_router packagepackageflutter/packages repository. See also p: labels.team-ecosystemOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem team

    Type

    No type

    Projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions