Skip to content

Fix stale EAV attribute code in setup cache after rename (#38636)#40980

Open
lbajsarowicz wants to merge 3 commits into
magento:2.4-developfrom
lbajsarowicz:fix/38636-eav-setup-attribute-code-cache
Open

Fix stale EAV attribute code in setup cache after rename (#38636)#40980
lbajsarowicz wants to merge 3 commits into
magento:2.4-developfrom
lbajsarowicz:fix/38636-eav-setup-attribute-code-cache

Conversation

@lbajsarowicz

Copy link
Copy Markdown
Contributor

Description (*)

Magento\Eav\Setup\EavSetup::getAttribute() populates the setup cache for each
attribute under two keys — its attribute_id and its attribute_code:

$setupCache->setRow($mainTable, $entityTypeId, $row['attribute_id'], $row);
$setupCache->setRow($mainTable, $entityTypeId, $row['attribute_code'], $row);

Magento\Setup\Module\DataSetup::updateTableRow() — used by
EavSetup::_updateAttribute() — refreshes only the attribute_id-keyed cache
entry after an UPDATE. The attribute_code-keyed entry is left untouched.

As a result, when an attribute is renamed and then re-added with the original
code in the same request:

$setup->updateAttribute($entityType, 'attribute', ['attribute_code' => 'attribute_old']);
$setup->addAttribute($entityType, 'attribute', [ /* new data */ ]);

addAttribute('attribute') calls getAttribute($entityType, 'attribute', 'attribute_id'),
which hits the stale code-keyed cache entry still pointing at the original
attribute id. addAttribute therefore treats it as an existing attribute and
runs updateAttribute() on it (renaming attribute_old back to attribute)
instead of inserting a new attribute — so nothing changes.

Fix

Invalidate the stale setup-cache entries in _updateAttribute() after the row
is updated. The pre-update attribute_code is captured before updateTableRow()
(which overwrites the id-keyed cache row), then the id-keyed and code-keyed
entries are removed. getAttribute() transparently re-reads from the database on
the next lookup.

Related Pull Requests

None

Fixed Issues (*)

Fixes #38636

Manual testing scenarios (*)

Using a single setup/data-patch instance:

  1. addAttribute($entityType, 'attribute', [...]).
  2. updateAttribute($entityType, 'attribute', ['attribute_code' => 'attribute_old']).
  3. addAttribute($entityType, 'attribute', [...]).
  4. Before the fix: step 3 renames the existing attribute back to attribute
    attribute_old no longer exists and no new attribute is created.
  5. After the fix: step 3 inserts a new attribute, and attribute_old
    retains its renamed code — both attributes exist as distinct records.

Contribution checklist (*)

  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All new or changed code is covered with tests (integration regression test
    added in EavSetupTest)
  • All automated tests passed successfully (unit, integration, static)

EavSetup::getAttribute() caches attribute rows under both attribute_id and
attribute_code keys, but updateTableRow() refreshes only the id-keyed entry.
After updateAttribute() changed an attribute_code, the stale code-keyed entry
survived, so a subsequent addAttribute() with the original code updated the
renamed attribute instead of inserting a new one. Invalidate the code-keyed
cache entries in _updateAttribute().

Fixes magento#38636
@m2-assistant

m2-assistant Bot commented Jul 10, 2026

Copy link
Copy Markdown

Hi @lbajsarowicz. Thank you for your contribution!
Here are some useful tips on how you can test your changes using Magento test environment.
❗ Automated tests can be triggered manually with an appropriate comment:

  • @magento run all tests - run or re-run all required tests against the PR changes
  • @magento run <test-build(s)> - run or re-run specific test build(s)
    For example: @magento run Unit Tests

<test-build(s)> is a comma-separated list of build names.

Allowed build names are:
  1. Database Compare
  2. Functional Tests CE
  3. Functional Tests EE
  4. Functional Tests B2B
  5. Integration Tests
  6. Magento Health Index
  7. Sample Data Tests CE
  8. Sample Data Tests EE
  9. Sample Data Tests B2B
  10. Static Tests
  11. Unit Tests
  12. WebAPI Tests
  13. Semantic Version Checker

You can find more information about the builds here
ℹ️ Run only required test builds during development. Run all test builds before sending your pull request for review.


For more details, review the Code Contributions documentation.
Join Magento Community Engineering Slack and ask your questions in #github channel.

@lbajsarowicz

Copy link
Copy Markdown
Contributor Author

@magento run all tests

@lbajsarowicz

Copy link
Copy Markdown
Contributor Author

@magento run all tests

@lbajsarowicz

Copy link
Copy Markdown
Contributor Author

@magento run all tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Changing the attribute name and adding the attribute again issue

1 participant