I'm seeing what feels like an oddity around UUIDs for pathauto pattern configurations, resulting in complexity around our config/code versioning workflow.

Repeatability

Every time a pattern is saved.

Steps to reproduce:

  1. Create a pathauto pattern
  2. Export configuration (drush config-export or via GUI)
  3. "Edit" the pattern and save, with or without changes
  4. Export configuration again

Expected result

UUID visible in the export steps remains consistent.

Actual result

The UUID is different, and is regenerated each time the pattern is saved.

Notes

This may be expected behaviour but it's causing us some workflow and config sync issues. (Although once we've stabilised our patterns it won't be an ongoing problem.)

We've been working around it in the meantime by generating UUIDs in production and manually replacing them in our local code before committing, but I'm worried this may have unintended consequences.

Issue fork pathauto-2895873

Command icon 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

Jimaginary created an issue. See original summary.

berdir’s picture

Version: 8.x-1.0 » 8.x-1.x-dev
Category: Support request » Bug report

Ah yes, that's the UUID of the conditions, not the UUID of the config entity.

That currently happens due to \Drupal\pathauto\Entity\PathautoPattern::addSelectionCondition() and how it is used in the UI. Would need to be refactored somehow to update the conditions instead. Conditions can be added or removed, so that might be a bit tricky to track.

But agreed that this is a bug.

nedjo’s picture

Status: Active » Postponed

Looks like this might be avoided by #3002529: Defer pathauto.pattern uuid config schema to config_entity. Postponing pending a resolution there.

berdir’s picture

Status: Postponed » Active

That's not related, this isn't the top-level UUID, it's the UUID of the conditions The UI needs to be adjusted to not replace the conditions everytime or atleast re-use the existing UUID's.

nedjo’s picture

@Berdir, ah, right, thx for catching that!

codebymikey made their first commit to this issue’s fork.

codebymikey’s picture

Assigned: Unassigned » codebymikey
Status: Active » Needs review

Added change to \Drupal\pathauto\Entity\PathautoPattern::addSelectionCondition() which persists the UUID if the configuration includes a uuid property saving the need to regenerate a unique UUID everytime.

berdir’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

This looks good at first glance, but it's a non-trivial amount of code to the form handling, would be great to make sure we have tests covering this. There is \Drupal\Tests\pathauto\FunctionalJavascript\PathautoUiTest::testPatternsWorkflow, where we add, edit and delete patterns, but we have little coverage for the conditions, specifically nothing about removing them.

So, would be good to extend that by removing the bundle condition and then also once save a pattern and ensure nothing on the config entity changes (load config entity, toArray(), save in UI without changes, then load again and compare)

mably made their first commit to this issue’s fork.

mably’s picture

Here's what the newly added tests cover:

  • testSelectionCriteriaUuidPreservedOnSave: Creates a pattern with a bundle condition, records the UUID, then re-saves it by calling addSelectionCondition() with the existing UUID (as the edit form does). Asserts the UUID stays the same after reload.
  • testSelectionCriteriaNewUuidGenerated: Verifies that adding conditions without a UUID correctly generates unique UUIDs for each condition. This ensures the fix didn't break the normal path for new conditions.
mably’s picture

Assigned: codebymikey » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs tests
mably’s picture

Assigned: Unassigned » berdir

Code review of MR #78

The two commits fix the issue where selection condition UUIDs were regenerated every time a pattern was saved, causing unnecessary config diffs for teams managing configuration through version control.

Changes

PathautoPattern::addSelectionCondition() — When a uuid key is present in the configuration array and a condition with that UUID already exists, the method now updates the existing condition in place instead of generating a new UUID. New conditions (without a UUID) still get a fresh UUID as before.

PatternEditForm — The form previously removed all bundle and language conditions then re-added them on every save, which triggered new UUID generation. It now builds a mapping of existing plugin IDs to their UUIDs and passes the existing UUID to addSelectionCondition(). Conditions are only removed when the user actually unchecks them (via new elseif branches).

Kernel tests — Two tests verify the fix:

  • testSelectionCriteriaUuidPreservedOnSave: confirms UUIDs remain stable after re-saving a pattern with existing conditions.
  • testSelectionCriteriaNewUuidGenerated: confirms new conditions still receive unique UUIDs.

The fix looks correct. The root cause (remove-then-readd pattern in the form) is replaced with an update-in-place approach, and the entity class properly supports UUID preservation.

mably’s picture

Category: Bug report » Feature request
mxr576’s picture

Status: Needs review » Closed (won't fix)

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

mably’s picture

Status: Closed (won't fix) » Needs work

Don't we need to remove all uuid from existing configuration first?

Maybe we should wait until the related issue is fixed before closing this one, or mark it as a duplicate.

mably’s picture

I feel like we could still have a problem with the condition configuration key names:

Config

Without this issue's fix, the config keys including the generated condition UUID would still change on each save.

But may be, it's not really a problem?

berdir’s picture

The conditions are still keyed by a UUID and that should be stable, this causes unessesary config changes

mably changed the visibility of the branch 2895873-replace-uuid-by-plugin-id to hidden.

berdir’s picture

Seems much easier now, nice. I don't think the kernel tests are doing much at this point, all the logic is in the form, so we should test that? We can possibly extend some existing edit tests and assert that the UUID's don't change ther?

mably’s picture

Status: Needs work » Needs review

Updated the test to simulate a form edit, ensuring it fails if the fix is not applied.

Also added some assertions to the PathautoUiTest functional Javascript test.

berdir’s picture

Looks good to me. Do we have existing coverage of removing language/bundle condition through the UI or should we add that too?

Then I think this is ready.

berdir’s picture

Assigned: berdir » Unassigned
Status: Needs review » Needs work

Added some feedback on the test, I think fine to merge then afterwards.

  • mably committed 79e1c43d on 8.x-1.x authored by codebymikey
    feat: #2895873 UUID is regenerated every time a pattern is saved
    
    By:...
mably’s picture

Status: Needs work » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.