InvalidArgumentException: The entity object refers to a removed translation (nl) and cannot be manipulated.

Created on 14 July 2022, over 2 years ago
Updated 31 July 2024, 4 months ago

Steps to reproduce:

Enable translations on a media entity type.
Create a media entity
Translate the media entity
Remove the translation without deleting the file
=> Fatal error: InvalidArgumentException: The entity object refers to a removed translation (nl) and cannot be manipulated. in /.../core/lib/Drupal/Core/Entity/ContentEntityBase.php on line 580

Full stack trace led me to the "MediaDeleteForm.php" on line 103.
Reverting the checks in the if fixed the problem.
Although not actually fixed, this should cover 99% of use case. Since users will never delete the file when deleting a translation. That would live the original language entity broken. (maybe better to block this off completely?)

Attached is a patch that simply switches the checks in the if-condition.

πŸ› Bug report
Status

Needs work

Version

1.1

Component

Code

Created by

πŸ‡§πŸ‡ͺBelgium weseze

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • First commit to issue fork.
  • @jumpsuitgreen opened merge request.
  • πŸ‡ΊπŸ‡ΈUnited States jumpsuitgreen

    Attached is the patch I'm using in production in case anyone needs it.

  • Status changed to Needs work almost 2 years ago
  • πŸ‡§πŸ‡ͺBelgium weseze

    This will not fix the issue, it will just create more difficult to debug issues...
    It is perfectly fine to create media entities in a non-default language and add translation to the default language.

    We should check if the entity is the original translation as suggested by @larowlan

  • πŸ‡ΊπŸ‡ΈUnited States jumpsuitgreen

    Thanks, @weseze. Regarding the "…more difficult debug issues" are those caused by the reversing of the conditions in the if() statement of the submitForm()? The only thing I added happens in the buildForm() function of the MediaDeleteForm classβ€”it checks if the media item being deleted is in the default language. If not, the option to delete the related file when deleting the translation is removed. It doesn't prevent the deletion (or creation) of the translated media item itself. If a translated file has been uploaded to the translated media item, its status will be marked as temporary if the translation referencing it has been deleted. Let me know and I'll rework.

  • πŸ‡ΊπŸ‡ΈUnited States jumpsuitgreen

    @weseze,
    In the submitForm() function, I reversed (again) the checks in the if() statement which puts them in their original order. I then wrapped the whole if() block inside a check of the media to ensure it only runs on the default language. When I test locally through the UI, I can

    1. create a new media item in default language
    2. add a translation of the media entity
    3. delete the translation the media entity
    4. create a new translation of the original media entity
    5. upload a translated file to the translation
    6. delete the translation which sets the translated file to temporary (since it is no longer is referenced)
    7. delete the original media entity and associated file

    The buildForm() function checks the media to determine if it is the default language and only adds the option to delete the associated file if isDefault() returns true. In short, deleting the associated file is only allowed if the media being deleted is the default language. Translations don't provide the option at all relying instead on trash collection to remove the file since it may be difficult to tell by the name if the file is a translated version or not.

    Let me know if this helps, or if I'm still missing something.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    Thanks, can we reverse the if and just call the parent and return early, rather than adding another if around the code, less complexity++

    We still need a test here too, because this is something that could easily be overlooked in manual testing.

  • πŸ‡ΊπŸ‡ΈUnited States jumpsuitgreen

    @larowlan
    That makes sense. Here is what the code looks like now.

    buildForm()
    Your original code is there but now preceded by a language check of the media entity. If not the default language, it calls the parent form function and returns early.

    submitForm()
    Again, your original code is there but now preceded by a language check of the media entity which returns early if the media entity is not the default language.

    Here are the local steps I went through for testing:

    1. Created a new media item in default language
    2. Created a translation without uploading a translated file
    3. Deleted the translation
    4. Created a new translation and uploaded/associated a translated file
    5. Deleted the translation
    6. Verified the associated, translated file was demoted to "Temporary" status
    7. Created a new translation and uploaded/associated a translated file (again)
    8. Deleted the media item entirely (default language and translation) including the associated file
    9. Verified the default language file had been deleted
    10. Verified the second translated file was also demoted to "Temporary" status

    Let me know if there are any other manual tests I should run through.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    Thanks, that looks great - can we get a test for this use-case?

  • When the media's default language is not the site's default language, the checkbox will not be displayed.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.4 + Environment: PHP 8.1 & MySQL 5.7
    last update 10 months ago
    5 pass, 4 fail
  • πŸ‡³πŸ‡±Netherlands MarcKwee

    I think we can easily fix this by turning the logic around in the Submit handler.

  • πŸ‡³πŸ‡±Netherlands MarcKwee

    There was a small mistake in my last patch. When you delete the defaultTranslation Media entity. It did not correctly delete the files of the translation media entities, even though those entities will no longer exist.

  • πŸ‡³πŸ‡±Netherlands MarcKwee

    I updated the patch so it also works with the bulk delete functionality.

Production build 0.71.5 2024