Skip to content

URL::defaults() + route group prefix causes positional parameter misalignment in route() calls #56604

@ibilalkhilji

Description

@ibilalkhilji

Laravel Version

12.22.1

PHP Version

8.2.3

Database Driver & Version

No response

Description

When a route has a parameter in the group prefix (e.g. {workspace:uuid?}) and its value is set via URL::defaults() in middleware, calling route() with positional parameters for other route parameters results in Laravel incorrectly assigning values.

The prefix parameter gets overwritten by the first positional parameter, and the intended parameter is left missing — often causing errors or producing URLs with an empty ?workspace= query string.

Note: this works without any issues in v12.3.0

Steps To Reproduce

  1. Define routes:
Route::group(['prefix' => 'app/{workspace:uuid?}', 'as' => 'app.', 'middleware' => [EnsureCurrentWorkspace::class]], function () {
        Route::get('', function (Workspace $workspace) {
            return view('dashboard');
        })->name('dashboard');

        Route::group(['prefix' => 'customers', 'as' => 'customers.', 'controller' => CustomerController::class], function () {
            Route::get('', 'index')->name('index');
            Route::get('create', 'create')->name('create');
            Route::post('create', 'store')->name('store');
            Route::get('modify/{customer}', 'modify')->name('modify');
            Route::post('modify/{customer}', 'update')->name('update');
            Route::delete('delete/{customer}', 'destroy')->name('delete');
        });
});
  1. In Middleware:
class EnsureCurrentWorkspace
{
    /**
     * Handle an incoming request.
     *
     * @param Closure(Request): (Response) $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        if ($request->user() && $request->route()->parameter('workspace') != null) {
            auth()->user()->workspaces->where('id', $request->route()->parameter('workspace')->id)->firstOrFail();
            URL::defaults(['workspace' => $request->route()->parameter('workspace')->uuid]);
        } else if ($workspace = Workspace::where('uuid', $request->route()->parameter('workspace'))->first()) {
            URL::defaults(['workspace' => $workspace->uuid]);
        } else
            if ($request->path() != 'workspaces')
                return Redirect::to('workspaces');
        return $next($request);
    }
}
  1. Route Call:
route('app.customers.modify',$customer->id)

Expected Behavior
Should generate:
/app/7b1c3cbe-675e-43cc-aed6-55bc36e7f79a/customers/123

Actual Behavior

Illuminate\Routing\Exceptions\UrlGenerationException
Missing required parameter for [Route: app.customers.modify] [URI: app/{workspace?}/customers/modify/{customer}] [Missing parameter: customer].

View:

<a href="{{ route('app.customers.modify',$customer->id) }}" class="btn btn-sm btn-primary">Edit</a>

When writing the route like:

<a href="{{ route('app.customers.modify',['customer'=>$customer->id]) }}" class="btn btn-sm btn-primary">Edit</a>

It works without any issues but have to rewrite everywhere and its too hectic for bigger projects

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions