Repository: TanStack/router (ts)

Issue:
Route Not found when using nested groups
### Describe the bug

Describe the bug
When i am using nested route groups i am not able to visit pages that are inside the second group. 

Say that i have a path that is "/(auth)/org/(graphql)/$orgId/revenue" I will not be able to visit "(auth)/org/(graphql)$orgId/revenue" but i can visit "(auth)/org/$orgId" since it is not inside two groups.

On version: "@tanstack/react-router": "^1.44.1"


### Your Example Website or App

https://stackblitz.com/edit/github-isj4z7?file=src%2Froutes%2F__root.tsx

### Steps to Reproduce the Bug or Issue

Attempt to visit /org/$orgId/revenue

### Expected behavior

I would expect to see the route. 

### Screenshots or Videos

_No response_

### Platform

Platform
OS: [MacOs]
Browser: [Arc]
Version: [Version 1.46.0 (50665)]


### Additional context

I had the issue #1725 but i never implemented the pattern in my app before now. So the error has been there from version 1.0 and i am assuming this is a bug due to the fix on the related issue

Pull request description:
fix(router-generator): throw an error when a route configuration is found for a grouping identifier
Stemmig from #1939.

The router-generator currently allows a user to create a route configuration named `(group).tsx` this should not be allowed, as a route-group cannot have a route configuration.

Closes #1939 

Patch:
diff --git a/packages/router-generator/src/generator.ts b/packages/router-generator/src/generator.ts
index 0fd91bd9c..591d4e110 100644
--- a/packages/router-generator/src/generator.ts
+++ b/packages/router-generator/src/generator.ts
@@ -9,6 +9,7 @@ let latestTask = 0
 export const rootPathId = '__root'
 const routeGroupPatternRegex = /\(.+\)/g
 const possiblyNestedRouteGroupPatternRegex = /\([^/]+\)\/?/g
+const disallowedRouteGroupConfiguration = /\(([^)]+)\).(ts|js|tsx|jsx)/
 
 export type RouteNode = {
   filePath: string
@@ -82,6 +83,12 @@ async function getRouteNodes(config: Config) {
             routePath = routePath.replaceAll(routeFilePrefix, '')
           }
 
+          if (disallowedRouteGroupConfiguration.test(dirent.name)) {
+            const errorMessage = `A route configuration for a route group was found at \`${filePath}\`. This is not supported. Did you mean to use a layout/pathless route instead?`
+            logger.error(`ERROR: ${errorMessage}`)
+            throw new Error(errorMessage)
+          }
+
           const variableName = routePathToVariable(routePath)
 
           // Remove the index from the route path and
diff --git a/packages/router-generator/tsconfig.json b/packages/router-generator/tsconfig.json
index b36d1bf92..604fde555 100644
--- a/packages/router-generator/tsconfig.json
+++ b/packages/router-generator/tsconfig.json
@@ -1,4 +1,5 @@
 {
   "extends": "../../tsconfig.json",
-  "include": ["src", "vite.config.ts"]
+  "include": ["src", "vite.config.ts", "tests"],
+  "exclude": ["tests/generator/**/**"]
 }


Test patch:
diff --git a/packages/router-generator/tests/deny-route-group-config.test.ts b/packages/router-generator/tests/deny-route-group-config.test.ts
new file mode 100644
index 000000000..a1457f877
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config.test.ts
@@ -0,0 +1,62 @@
+import { join } from 'node:path'
+import { describe, expect, it } from 'vitest'
+
+import { generator, getConfig } from '../src'
+import type { Config } from '../src'
+
+function makeFolderDir(folder: string) {
+  return join(process.cwd(), 'tests', 'deny-route-group-config', folder)
+}
+
+async function setupConfig(
+  folder: string,
+  inlineConfig: Partial<Omit<Config, 'routesDirectory'>> = {},
+) {
+  const { generatedRouteTree = '/routeTree.gen.ts', ...rest } = inlineConfig
+  const dir = makeFolderDir(folder)
+
+  const config = await getConfig({
+    disableLogging: true,
+    routesDirectory: dir,
+    generatedRouteTree: dir + generatedRouteTree,
+    ...rest,
+  })
+  return config
+}
+
+type TestCases = Array<{
+  folder: string
+  expectedError: string
+}>
+
+describe('deny-route-group-config throws', () => {
+  it.each([
+    {
+      folder: 'flat-flat',
+      expectedError:
+        'A route configuration for a route group was found at `(group).tsx`. This is not supported. Did you mean to use a layout/pathless route instead?',
+    },
+    {
+      folder: 'nested-flat',
+      expectedError:
+        'A route configuration for a route group was found at `(group).tsx`. This is not supported. Did you mean to use a layout/pathless route instead?',
+    },
+    {
+      folder: 'flat-nested',
+      expectedError:
+        'A route configuration for a route group was found at `nested/(group).tsx`. This is not supported. Did you mean to use a layout/pathless route instead?',
+    },
+    {
+      folder: 'nested-nested',
+      expectedError:
+        'A route configuration for a route group was found at `nested/(group).tsx`. This is not supported. Did you mean to use a layout/pathless route instead?',
+    },
+  ] satisfies TestCases)(
+    'should throw an error for the folder: $folder',
+    async ({ folder, expectedError }) => {
+      const config = await setupConfig(folder)
+
+      expect(() => generator(config)).rejects.toThrowError(expectedError)
+    },
+  )
+})
diff --git a/packages/router-generator/tests/deny-route-group-config/flat-flat/(group).index.tsx b/packages/router-generator/tests/deny-route-group-config/flat-flat/(group).index.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/flat-flat/(group).index.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/flat-flat/(group).tsx b/packages/router-generator/tests/deny-route-group-config/flat-flat/(group).tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/flat-flat/(group).tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/flat-flat/__root.tsx b/packages/router-generator/tests/deny-route-group-config/flat-flat/__root.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/flat-flat/__root.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/flat-flat/about.tsx b/packages/router-generator/tests/deny-route-group-config/flat-flat/about.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/flat-flat/about.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/flat-nested/__root.tsx b/packages/router-generator/tests/deny-route-group-config/flat-nested/__root.tsx
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/router-generator/tests/deny-route-group-config/flat-nested/about.tsx b/packages/router-generator/tests/deny-route-group-config/flat-nested/about.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/flat-nested/about.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/flat-nested/nested/(group).index.tsx b/packages/router-generator/tests/deny-route-group-config/flat-nested/nested/(group).index.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/flat-nested/nested/(group).index.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/flat-nested/nested/(group).tsx b/packages/router-generator/tests/deny-route-group-config/flat-nested/nested/(group).tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/flat-nested/nested/(group).tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/nested-flat/(group).tsx b/packages/router-generator/tests/deny-route-group-config/nested-flat/(group).tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/nested-flat/(group).tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/nested-flat/(group)/index.tsx b/packages/router-generator/tests/deny-route-group-config/nested-flat/(group)/index.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/nested-flat/(group)/index.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/nested-flat/__root.tsx b/packages/router-generator/tests/deny-route-group-config/nested-flat/__root.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/nested-flat/__root.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/nested-flat/about.tsx b/packages/router-generator/tests/deny-route-group-config/nested-flat/about.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/nested-flat/about.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/nested-nested/__root.tsx b/packages/router-generator/tests/deny-route-group-config/nested-nested/__root.tsx
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/router-generator/tests/deny-route-group-config/nested-nested/about.tsx b/packages/router-generator/tests/deny-route-group-config/nested-nested/about.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/nested-nested/about.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/nested-nested/nested/(group).tsx b/packages/router-generator/tests/deny-route-group-config/nested-nested/nested/(group).tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/nested-nested/nested/(group).tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/deny-route-group-config/nested-nested/nested/(group)/index.tsx b/packages/router-generator/tests/deny-route-group-config/nested-nested/nested/(group)/index.tsx
new file mode 100644
index 000000000..ab504e42e
--- /dev/null
+++ b/packages/router-generator/tests/deny-route-group-config/nested-nested/nested/(group)/index.tsx
@@ -0,0 +1,1 @@
+/** */
diff --git a/packages/router-generator/tests/generator.test.ts b/packages/router-generator/tests/generator.test.ts
index 9d97d91e9..c4bb0c5e5 100644
--- a/packages/router-generator/tests/generator.test.ts
+++ b/packages/router-generator/tests/generator.test.ts
@@ -1,14 +1,15 @@
-import fs from 'fs/promises'
-import { join } from 'path'
-import { describe, it, expect } from 'vitest'
+import fs from 'node:fs/promises'
+import { join } from 'node:path'
+import { describe, expect, it } from 'vitest'
 
-import { generator, getConfig, type Config } from '../src'
+import { generator, getConfig } from '../src'
+import type { Config } from '../src'
 
 function makeFolderDir(folder: string) {
   return join(process.cwd(), 'tests', 'generator', folder)
 }
 
-async function readDir(...paths: string[]) {
+async function readDir(...paths: Array<string>) {
   const folders = await fs.readdir(
     join(process.cwd(), 'tests', 'generator', ...paths),
   )