Skip to content

[BUGFIX] Prevent duplicate attribute slug writes that break admin attribute saves#363

Closed
JKetelaar wants to merge 2 commits into
EmicoEcommerce:masterfrom
JKetelaar:fix/attribute-slug-unique-constraint
Closed

[BUGFIX] Prevent duplicate attribute slug writes that break admin attribute saves#363
JKetelaar wants to merge 2 commits into
EmicoEcommerce:masterfrom
JKetelaar:fix/attribute-slug-unique-constraint

Conversation

@JKetelaar

@JKetelaar JKetelaar commented Apr 1, 2026

Copy link
Copy Markdown

Problem

When saving product attributes in Magento admin we hit:
Could not save the page: Unique constraint violation found.

In our case this started after upgrading to v8.9.1+ and was still reproducible on v8.11.0.

How To Reproduce

  1. Use tweakwise/magento2-tweakwise v8.11.0.
  2. Make sure tweakwise_attribute_slug already contains slug rows for an existing product attribute (common on live stores after first save/regeneration).
  3. In Magento admin, go to Catalog > Attributes > Product, open an existing attribute and click save.
  4. Save the same attribute again (or save after changing a store-view label).
  5. Observe admin error: Could not save the page: Unique constraint violation found.

Where It Was Introduced

Likely introduced with commit 14671d5 (add store id to table, included in v8.8.0+, therefore also v8.9.1).

That change made findBySlug() store-scoped (slug + store_id) while the table still has a global unique index on slug from InstallSchema. This can cause false negatives during existence checks and eventually duplicate insert attempts that fail on DB unique constraints.

Root Cause

AttributeSlugRepository::save() may attempt to insert a new row even when an attribute/store row already exists, because it does not reliably load/set the existing entity ID before save.

Additionally, slug collision checks were limited by store while slug uniqueness can still conflict globally in existing datasets.

Fix

  • Load existing slug row by attribute + store_id and set its ID before saving (update instead of duplicate insert).
  • Check slug collisions by slug value when generating suffixes, and only treat as same record when both attribute and store_id match.

Result

Repeated admin attribute saves no longer fail with unique constraint violations, and slug generation remains deterministic across stores.

Related issue: #337.

Update existing attribute/store slug rows before persisting and resolve slug collisions globally so repeated attribute saves no longer hit unique constraint violations.
@JKetelaar JKetelaar marked this pull request as ready for review April 1, 2026 13:49
@ahuininga-orisha

Copy link
Copy Markdown
Collaborator

@JKetelaar Thx for the pull request.

I don't think this is the correct solution. The slug doesn't have to be unique, just unique per store. I'll make an patch that fixes the database index.

@JKetelaar

Copy link
Copy Markdown
Author

@JKetelaar Thx for the pull request.

I don't think this is the correct solution. The slug doesn't have to be unique, just unique per store. I'll make an patch that fixes the database index.

Thanks, I agree the current schema is inconsistent with the intended behaviour.
The codebase treats attribute slugs as store-scoped, not globally unique:

  • lookups are done by slug + store_id
  • slug resolution checks the current store first and then falls back to store 0

That said, I do not think this is only a database-index issue. The current save flow can still try to insert a new row without loading the existing row ID first, which can hit the (attribute, store_id) unique constraint as well when the logical record already exists.

@ahuininga-orisha

Copy link
Copy Markdown
Collaborator

@JKetelaar I've created an new pull request that should fix both issues #381. I think this is an nicer solution for this problem

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.

2 participants