Problem/Motivation
When inserting selected media there are scenarios where bundle labels cannot be generated resulting in AJAX errors and the users inability to insert their selected image.
An AJAX HTTP error occurred.
HTTP Result Code: 200
Debugging information follows.
Path: /layout_builder/update/block/overrides/node.1/0/0/b7bf67d6-53e6-4229-a2fb-2649a27c1646?destination=/node/1/layout&_wrapper_format=drupal_dialog.off_canvas&ajax_form=1
StatusText: OK
ResponseText: Warning: array_map(): Argument #2 should be an array in /app/web/core/modules/media_library/src/Plugin/Field/FieldWidget/MediaLibraryWidget.php on line 826
As noted the 2nd argument to the `array_map` function on this line is not always an array which results in the error.
Steps to reproduce
Simple
- Do a standard install
- Enable media and media_library
- Add a new Media field to Basic page content, but do NOT select any Media types to reference.This means you cannot save the settings form, but that's ok. The field has been created at this point.
- Create a new Basic page and use Media Library (which should be set by default) to add Media to your new field.
- View the logs and note the php warning above
Original
- Create a custom block type with a media field with a form display of "Media Library". Note: do not limit by bundle (ie: media type)
- Create a new content type that uses `layout_builder`
- Create a new node using the content type you've created and save.
- Click the layout action tab to modify the layout for your node.
- Create a new section and add your new block type
- Click the add media in the add block form to upload your media.
- When attempting to "insert" media a console error should be generated. Note: the media entity will be created just not inserted.
Proposed resolution
The 2nd argument passed to `array_map` needs a fallback to an empty array if the field is not limited by media type.
Remaining tasks
Review provided patches.
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet
None
Comment | File | Size | Author |
---|---|---|---|
#23 | interdiff_12-23.txt | 937 bytes | danflanagan8 |
#23 | 3190261-23.patch | 1.99 KB | danflanagan8 |
#15 | interdif_9-15.txt | 1.05 KB | danflanagan8 |
#15 | 3190261-15.patch | 2.12 KB | danflanagan8 |
#9 | 3190261--9--FAIL.patch | 1.08 KB | danflanagan8 |
Issue fork drupal-3190261
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
doostinharrell CreditAttribution: doostinharrell at Avid New Media commentedComment #3
larowlanThanks for the detailed report
We can use ?? here to make the solution even simpler
Can we get a test demonstrating the issue?
Comment #4
doostinharrell CreditAttribution: doostinharrell at Avid New Media commentedComment #5
doostinharrell CreditAttribution: doostinharrell at Avid New Media commented@larowlan I have uploaded an updated patch with your recommendation.
Comment #6
doostinharrell CreditAttribution: doostinharrell at Avid New Media commentedComment #7
larowlanThanks, we just need a test to demonstrate the bug and that it's fixed
Comment #8
idebr CreditAttribution: idebr at iO commentedIn the user interface 'Media type' is a required field when configuring a Media field. Perhaps the current code is working as intended?
Comment #9
danflanagan8This is true, but you don't have to save those field settings when creating the field, leaving the media type unrestricted. This situation is tested for in media_library using a field called 'field_null_types_media' defined in its test module. So I think we can try to use that field to expose this bug.
I thought I'd be able to expose the bug by just inserting a media item into that field as part of EntityReferenceWidgetTest. It doesn't seem to be failing. Maybe because it's just a php warning and not a true error? Not sure. I'm attaching my attempt at a fail test just to maybe get the ball rolling. And I'm holding out hope that maybe the test runner here is configured differently from mine and will end up flagging the warning.
For the record, I was able to reproduce the warning manually, even without layout builder. I never got anything fatal. Just a warning in the logs.
Comment #10
danflanagan8Well, the fail test passed, which is a failure. And I saw no evidence of warnings getting logged or anything like that. I'll change to needs work. I'm wondering what ideas other people might have.
Comment #11
danflanagan8I stumbled across this issue again and I think I have a fail test for it.
The difficulty here is that we are testing for a php warning (not a fatal error or exception) in an ajax callback. I've had trouble testing for warnings like this before (see https://www.drupal.org/project/drupal/issues/3106460#comment-14213609).
I modeled the test here after something I found in core: https://git.drupalcode.org/project/drupal/-/blob/9.3.x/core/modules/syst...
So it's ugly, but not without precedent.
Comment #12
danflanagan8I canceled the test for the patch above because I came up with a slightly more convincing version by making it clear that only relevant php errors would be found. I like this a lot better.
Comment #14
danflanagan8Hmmm, that was weird. The patch in #12 failed with:
I'm surprised that happened in #12 but not in #9, which was run 10 months ago against 8.9.x. Is there something different with test configuration in the last 10 months?
I'm going to re-test the patch on #9 with D9.3.x and see if I get the same failure.
Comment #15
danflanagan8Yes, re-running #9 on 9.3.x resulted in the same error, which was the error I was hoping to trigger 10 MONTHS AGO!!! Apparently I was ahead of my time. ;)
So here I add the fix from #2 to test against the fail test.
Although the fix in #4 looks more elegant, it didn't fix the problem for me when I was testing manually. Apparently
$element['#target_bundles']
isFALSE
instead of NULL. Maybe it's a side-effect ofNestedArray::getValue
?Comment #16
danflanagan8I updated the IS with a "Simple" set of steps to reproduce. It doesn't involve Layout Builder, which makes it a tad easier.
Comment #17
paulocsI'll do a review.
Comment #18
paulocsPatch looks good and it has tests.
I confirm that the warning message is correctly fixed.
Thanks @danflanagan8
Comment #19
lauriiiTagging for subsystem maintainer review to get them to weigh on #8.
Comment #20
phenaproximaI agree with @danflanagan8's assessment in #9. Media Library supports the field not specifying any target bundles, and we do test for that, and therefore I think this bug fix is the correct approach.
However, reviewing the code, I'm wondering something: in MediaLibraryWidget::formElement(), I see this line:
'#target_bundles' => $settings['target_bundles'] ?? FALSE,
It's not explained why #target_bundles is set to FALSE, rather than just an empty array. The rest of the code which uses this property basically expects an array, and in fact could be simplified by it. So maybe it would make sense to just change this line to
$settings['target_bundles'] ?? []
, and add a comment explaining why we're doing it? That way we don't have to deal with FALSE, which as far as I can tell just confuses things.Comment #21
danflanagan8Here's a patch with that updated approach suggested by @phenaproxima. The interdiff is the fix. I'm having trouble running tests locally, so I'm not totally sure how this will turn out. It smells right to me, but we'll see.
Comment #22
phenaproximaComment #23
danflanagan8Re-roll of #21. Interdiff is relative to the fail test such that it shows the fix, which is the new approach suggested in #20.
NOTE: The first commit number in the interdiff filename is wrong. It should be 9, not 12. The contents of the interdiff are correct. Sorry for the confustion.
Comment #24
danflanagan8That looks like a good result.
Also note that the fail patch in #9 was triggered manually to re-run in 9.4.x. It applied and failed as expected. (https://www.drupal.org/pift-ci-job/2238945)
Comment #25
chr.fritschLooks good to me. Thx @danflanagan8
Comment #26
phenaproximaRe-titling for clarity.
Comment #28
SpokjeBack to RTBC per #25 after #3255836: Test fails due to Composer 2.2 solved the unrelated test failure.
Comment #30
catchCommitted/pushed to 10.0.x, cherry-picked to 9.4.x and 9.3.x, thanks!