How-To: Avoid Laravel Wayfinder Route-Name Collisions β
Laravel Wayfinder generates TypeScript helpers from your route definitions so the Inertia frontend can call them type-safely. A small set of method/route names break the generator silently β the build still passes, but vue-tsc errors and frontend autocomplete dies.
The symptom β
[vue-tsc] error TS2300: Duplicate identifier 'options'
[vue-tsc] error TS2440: Import declaration conflicts with local declaration of 'options'β¦in a Wayfinder-generated file (under resources/js/wayfinder/).
The build succeeds because Wayfinder errors are not fatal, but the affected route helper is unusable.
The cause β
Wayfinder names the generated TypeScript symbol after the controller method. If the method name is a reserved/global identifier in the emitted module (e.g. options, which collides with HTTP OPTIONS / fetch RequestInit.options), the output is invalid TS.
Known collisions:
| Method name | Why it breaks |
|---|---|
options | Collides with HTTP OPTIONS and fetch options type |
delete | Reserved word in some emit contexts |
import / export | TS keywords |
default | TS keyword |
The fix β
Rename the controller method to something domain-specific. Update the route name too β leave the URL path alone so the API contract is preserved.
// app/Http/Controllers/Admin/LegacyImportMappingController.php
// Before β breaks Wayfinder
public function options(Request $request, string $type): JsonResponse { ... }
// After
public function targetOptions(Request $request, string $type): JsonResponse { ... }// routes/web.php
// Before
Route::get('legacy-import/mappings/{type}/options', [LegacyImportMappingController::class, 'options'])
->name('legacy-import.mappings.options');
// After
Route::get('legacy-import/mappings/{type}/options', [LegacyImportMappingController::class, 'targetOptions'])
->name('legacy-import.mappings.target-options');Re-run the dev server or npm run build to regenerate the Wayfinder TS.
How to detect this early β
# Fail fast on Wayfinder type errors
npx vue-tsc --noEmitAdd this to your pre-commit hook or CI. Wayfinder errors hide in a sea of build output otherwise.
When you can't rename β
If you genuinely need the URL segment to be /options, that's fine β only the controller method name matters to Wayfinder. The path stays.
public function targetOptions() { ... }
Route::get('mappings/{type}/options', [Ctrl::class, 'targetOptions'])
->name('mappings.target-options');Checklist β
- [ ] Don't name a controller method
options,delete,import,export, ordefault - [ ] After renaming, update the route's
->name(...)too (so otherroute()calls stay consistent) - [ ] Run
npx vue-tsc --noEmitto confirm Wayfinder TS compiles - [ ] Update any callers of the old route name (
route('legacy-import.mappings.options')β new name)
Related β
- Memory:
wayfinder-options-route-name-collision - Commit:
f6cead2 fix(data-mappings): rename options route to avoid Wayfinder name collision
