Skip to content

[5.x]: New entry's URI stays stuck on the temp slug in other sites, if the site it's first created on has no URL format #19495

Description

@scoch5

What happened?

Description

In a multi-site section with propagationMethod: all, if a new entry is first created on a site that has no URL format for that section (hasUrls: false), the entry's URI on the other sites (which do have URLs) can get permanently stuck on the temporary placeholder slug (__temp_xxxxxxxx), even though the slug column itself is correctly regenerated from the title everywhere.

This looks closely related to #16347, which was fixed in 5.5.8 by changing Drafts::removeDraftData() to save with $propagate = true, then reverted back to $propagate = false in a follow-up "better fix" (to avoid a regression with programmatic post-save changes on unpublished drafts being overwritten — craftcms/ckeditor#426), replacing it with a narrower fix in SlugValidator that only guarantees the slug gets regenerated at publish time, not the URI on other sites.

Root cause as far as I can trace it:

Combine the two: if an entry's "home" site for editing has no URL format, the 'uri' dirty condition in _propagateElement() can never be satisfied again after the very first save (when the entry was brand new and isNewForSite was still true for the other sites) — and that first save is often the moment EntriesController::actionCreate() assigns a temp slug because the title hasn't been typed yet:

https://github.com/craftcms/cms/blob/5.10.9/src/controllers/EntriesController.php#L166-L174

So the URI baked in on the other (URL-having) sites at creation time is the temp one, and nothing in the normal edit → autosave → publish flow ever revisits it — because propagation is either skipped (removeDraftData) or gated on a condition (uri dirty) that can't fire from a source site whose URI is permanently null.

Manually resaving the entry (a full resave/entries or an explicit CP save with resaving/scenario forcing setElementUri() again) fixes it, because that's the third, ungated condition ($element->resaving).

Steps to reproduce

  1. Create a multi-site section propagated to 2 sites, propagationMethod: all.
  2. Site A: hasUrls: false for this section. Site B: hasUrls: true, e.g. uriFormat: 'foo/{slug}'.
  3. Make Site A the "current"/default site in the CP (or otherwise create + edit + publish the entry entirely from Site A's tab).
  4. Click "+ New entry" (Craft immediately creates an unpublished draft; since no title has been typed yet, the slug is ElementHelper::tempSlug(), e.g. __temp_abc123).
  5. Type a title, let autosave run, then click Save/Publish — all while staying on Site A's tab.
  6. Check Site B's elements_sites row for this entry.

Expected behavior

Site B's slug and uri should both reflect the real, title-derived slug (e.g. slug: foo-bar, uri: foo/foo-bar).

Actual behavior

Site B's slug is correct (foo-bar), but uri is still the original placeholder (foo/__temp_abc123) — a real, published, correctly-titled entry ends up permanently reachable only at a URL containing a random temp string, until it's manually resaved (which then breaks any link to the temp URL that had already been shared/indexed).

Confirmed as the trigger: giving Site A a real URL format for the section (hasUrls: true + a uriFormat) made the problem stop occurring for newly created entries. Also confirmed via direct DB inspection on a production instance affected by this: dozens of entries created over many months, all created/edited by the same user through the CP, all showing this exact slug correct / uri stale-temp pattern, all with dateCreated == the first save where isNewForSite would have been true.

Craft CMS version

5.10.9

PHP version

8.2

Operating system and version

No response

Database type and version

MySQL 8.0.40

Image driver and version

No response

Installed plugins and versions

No response

Activity

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions