Skip to content

Inconsistent behavior of /** syntax in TrieRouter vs other routers #4623

Description

@NiebieskiRekin

What is the feature you are proposing?

Description

While /** is not explicitly documented as standard Hono syntax, it appears to be supported (or treated equivalently to /*) by RegExpRouter, PatternRouter, and LinearRouter.

However, TrieRouter (which SmartRouter defaults to in many cases) fails to match routes defined with /**, returning a 404. This creates a hidden pitfall where switching routers (or adding routes that cause SmartRouter to switch internal strategies) breaks existing route matching.

Code sample

The following code demonstrates that TrieRouter returns 404 for /auth/**, but changing the router to another one or the route to /* makes it work.

import { serve } from '@hono/node-server'
import { Hono } from 'hono'
import { getRouterName, showRoutes } from 'hono/dev';
import { PatternRouter } from 'hono/router/pattern-router';
import { LinearRouter } from 'hono/router/linear-router';
import { RegExpRouter } from 'hono/router/reg-exp-router';
import { TrieRouter } from 'hono/router/trie-router';

const app = new Hono({router: new TrieRouter()})
  .on(["POST", "GET"], "/auth/**", (c) => c.json({})) // Note **

showRoutes(app)

serve({
  fetch: app.fetch,
  port: 3001
}, (info) => {
  console.log(getRouterName(app));
  fetch(`http://localhost:${info.port}/auth/hello`).then(async (res)=>{
    if (res.ok){
      console.log("OK!")
    } else {
      console.error("Error! "+res.status)
    }
  }
  )
})

Output:

POST  /auth/**
GET   /auth/**
TrieRouter
Error! 404

After changing routers:

RegExpRouter

const app = new Hono({router: new RegExpRouter()})
  .on(["POST", "GET"], "/auth/**", (c) => c.json({}))

Output:

POST  /auth/**
GET   /auth/**
RegExpRouter
OK!

PatternRouter

const app = new Hono({router: new PatternRouter()})
  .on(["POST", "GET"], "/auth/**", (c) => c.json({}))

Output:

POST  /auth/**
GET   /auth/**
PatternRouter
OK!

LinearRouter

const app = new Hono({router: new LinearRouter()})
  .on(["POST", "GET"], "/auth/**", (c) => c.json({}))

Output:

POST  /auth/**
GET   /auth/**
LinearRouter
OK!

After changing the route to /*

const app = new Hono({router: new TrieRouter()})
  .on(["POST", "GET"], "/auth/*", (c) => c.json({})) // Note *

Output:

POST  /auth/*
GET   /auth/*
TrieRouter
OK!

Proposal

Behavior should be consistent across routers.

If /** is intended to be supported as an alias for /* (or a recursive wildcard), TrieRouter should support it.

If /** is invalid syntax, other routers should ideally not match it, or Hono should warn during route registration or in the docs.

Currently, it works in 3 out of 4 routers.

TrieRouter:    404 Not Found
RegExpRouter:  200 OK
PatternRouter: 200 OK
LinearRouter:  200 OK

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions