Deleting a workout showed success in the UI, but after refresh, the workout was still there. The console showed:

Delete failed: 200 {success: false}

200 status. No error field. No server logs. The controller method wasn't being called at all.

The Investigation

I added a log to the first line of WorkoutController::destroy():

public function destroy(Workout $workout)
{
    \Log::info('Workout delete requested', ['workout_id' => $workout->id]);
    // ...
}

Nothing appeared. The route existed (php artisan route:list confirmed it), but something was intercepting the request before it got there.

The Shadowing Route

// Line 195 in routes/web.php
Route::delete('/planner/{type}/{id}', [DailyPlanController::class, 'delete']);

// Line 221 in routes/web.php
Route::delete('/planner/workouts/{workout}', [WorkoutController::class, 'destroy']);

The generic route was defined before the specific one. When DELETE /planner/workouts/44 came in, Laravel matched /planner/{type}/{id} first -- with type="workouts", id="44". The request went to DailyPlanController::delete().

That controller had a switch statement for known types:

public function delete(Request $request, $type, $id)
{
    $deleted = false;
    switch ($type) {
        case 'priority':  // ... break;
        case 'appointment':  // ... break;
        case 'note':  // ... break;
        case 'expense':  // ... break;
        // No case for 'workouts'!
    }
    return response()->json(['success' => $deleted]);  // false for unknown types
}

The switch fell through, returned {"success": false} with status 200. No error, no exception, no log.

The Fix

One line -- constrain the wildcard to only match valid types:

Route::delete('/planner/{type}/{id}', [DailyPlanController::class, 'delete'])
    ->where('type', 'priority|appointment|note|expense');

Now /planner/workouts/44 skips this route and reaches WorkoutController::destroy().

Why It Was Hard to Find

The 200 status made it look "successful." The valid JSON response didn't trigger error handling. No exceptions meant no logs. The specific route existed and was correctly defined -- but route order meant it never ran. The clue was the missing error field: my exception handler always includes one, so the response had to be coming from somewhere else entirely.