fix(entries): exclude current entry from slug uniqueness on update (#27)#28
Merged
sylvesterdamgaard merged 1 commit intoMay 5, 2026
Conversation
Closes cboxdk#27. `updateEntry()` always injected the entry's *current* slug into the FieldsValidator payload: $mergedData = array_merge($entry->data()->all(), $data); $mergedData['slug'] = $entry->slug(); // <-- always added `UniqueEntryValue` then ran against that slug without an exclusion, so Statamic found the slug on the entry being updated and rejected it as 'already taken'. Every update through the MCP tool failed, regardless of whether the caller passed a slug at all. Mirror the slug handling already used in `createEntry()`, with one small addition: pass `$entry->id()` as the `$except` argument so `UniqueEntryValue` excludes the current entry from the uniqueness check. Slug rename, idempotent slug, and slug-not-supplied paths are now all handled before blueprint validation. The line that re-injected the slug into `mergedData` is removed so `FieldsValidator` never sees the slug column. Tests: * `test_update_entry_without_slug_in_data_succeeds` — exact reproduction from cboxdk#27: update without slug now succeeds. * `test_update_entry_with_unchanged_slug_succeeds` — resending the current slug is idempotent. * `test_update_entry_with_new_unique_slug_succeeds` — renaming to a unique slug works. * `test_update_entry_to_existing_slug_returns_error` — colliding with another entry's slug still surfaces the validation error.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #27.
Reproduction (from the issue)
{ \"action\": \"update\", \"collection\": \"your_collection\", \"id\": \"<entry-uuid>\", \"data\": { \"title\": \"Updated Title\" } }fails with:
even though
slugis not part ofdata.Root cause
updateEntry()always re-injected the entry's current slug into the FieldsValidator payload:UniqueEntryValuethen ran against that slug without an exclusion, so Statamic found the slug on the entry being updated and rejected it as "already taken". Every update through the MCP tool failed.Fix
Mirror the slug handling already used in
createEntry(), with one small addition: pass$entry->id()as the$exceptargument soUniqueEntryValueexcludes the current entry from the uniqueness check. Slug-rename, idempotent-slug, and slug-not-supplied paths are now all handled before blueprint validation, and the line that re-injected the slug intomergedDatais removed soFieldsValidatornever sees the slug column.Test plan
Added four regression tests in
tests/Feature/Routers/EntriesRouterTest.php:test_update_entry_without_slug_in_data_succeeds— exact repro from Update action fails with "slug: This value has already been taken" for existing entries #27 (no slug field): update now succeeds.test_update_entry_with_unchanged_slug_succeeds— resending the current slug is idempotent.test_update_entry_with_new_unique_slug_succeeds— renaming to a unique slug works and is persisted.test_update_entry_to_existing_slug_returns_error— colliding with another entry's slug still surfaces the validation error (the legitimate case the original check was protecting against).Results:
vendor/bin/pest tests/Feature/Routers/EntriesRouterTest.php→ 18 passed; 0 failed (4 new + 14 pre-existing).vendor/bin/pest --filter test_update_entry→ 18 passed; 0 failed across feature + integration suites that exercise the update flow (DateNormalizationTest, GroupFieldBugTest, TermsFieldUpdateTest, UpdateEntryBugTest).Notes