@@ -448,7 +448,7 @@ defmodule AshJsonApi.Controllers.Helpers do
448448 Request . add_error ( request , error , :fetch_from_path )
449449
450450 % Ash.BulkResult { status: :error , errors: errors } ->
451- Request . add_error ( request , errors , :update )
451+ Request . add_error ( request , strip_bulk_index_from_errors ( errors ) , :update )
452452 end
453453 end
454454 end
@@ -635,7 +635,7 @@ defmodule AshJsonApi.Controllers.Helpers do
635635 Request . add_error ( request , error , :fetch_from_path )
636636
637637 % Ash.BulkResult { status: :error , errors: errors } ->
638- Request . add_error ( request , errors , :update )
638+ Request . add_error ( request , strip_bulk_index_from_errors ( errors ) , :destroy )
639639 end
640640 end
641641 end
@@ -1165,4 +1165,34 @@ defmodule AshJsonApi.Controllers.Helpers do
11651165 { :ok , updated }
11661166 end
11671167 end
1168+
1169+ # Strips the bulk operation index (0) from error paths.
1170+ # When using Ash.bulk_update/bulk_destroy for single-record operations,
1171+ # errors include a leading 0 index that should not appear in JSON:API responses.
1172+ defp strip_bulk_index_from_errors ( errors ) do
1173+ Enum . map ( errors , & strip_bulk_index_from_single_error / 1 )
1174+ end
1175+
1176+ defp strip_bulk_index_from_single_error ( error ) do
1177+ error
1178+ |> strip_path_from_error ( )
1179+ |> strip_path_from_inner_errors ( )
1180+ end
1181+
1182+ defp strip_path_from_error ( error ) do
1183+ case Map . get ( error , :path ) do
1184+ [ 0 | rest ] -> % { error | path: rest }
1185+ _ -> error
1186+ end
1187+ end
1188+
1189+ defp strip_path_from_inner_errors ( error ) do
1190+ case Map . get ( error , :errors ) do
1191+ errors when is_list ( errors ) and errors != [ ] ->
1192+ % { error | errors: Enum . map ( errors , & strip_bulk_index_from_single_error / 1 ) }
1193+
1194+ _ ->
1195+ error
1196+ end
1197+ end
11681198end
0 commit comments