Skip to content

Examine: Fix DocumentUrlService not initialized during Examine indexing after package upgrade#22243

Merged
AndyButland merged 2 commits intomainfrom
v17/bugfix/fix-race-condition-with-url-service-and-examine-index
Mar 25, 2026
Merged

Examine: Fix DocumentUrlService not initialized during Examine indexing after package upgrade#22243
AndyButland merged 2 commits intomainfrom
v17/bugfix/fix-race-condition-with-url-service-and-examine-index

Conversation

@AndyButland
Copy link
Copy Markdown
Contributor

@AndyButland AndyButland commented Mar 24, 2026

Description

This PR addresses an issue I found in testing:

  • Create a new install of 17.3.0-rc2
  • Complete the installer and stop the site
  • Add a package with a migration plan - e.g. dotnet add package Clean
  • Start the site again with the default of unattended package migrations

This error is seeing in the logs:

System.InvalidOperationException: The service needs to be initialized before it can be used.
   at DocumentUrlService.ThrowIfNotInitialized()
   at DocumentUrlService.GetUrlSegment(...)
   at ContentValueSetBuilder.GetValueSetsEnumerable(...)

It appears to be a race condition where ContentValueSetBuilder calls DocumentUrlService.GetUrlSegment() before the service is initialized, causing an InvalidOperationException during Examine indexing after a package upgrade,

Root Cause

When Umbraco restarts with pending package migrations, DocumentUrlServiceInitializerNotificationHandler skips initialization because the runtime level is Upgrade. Meanwhile, QueuedHostedService is already running and can process deferred Examine indexing tasks queued during/after migration execution — before DocumentUrlService.InitAsync() is ever called (either via ContentCacheRefresher.RefreshAll or the post-migration UmbracoApplicationStartingNotification).

Fix

Guard DocumentUrlService calls in ContentValueSetBuilder with an IsInitialized check. When not initialized, fall back to computing the URL segment directly from the content using the same GetUrlSegment extension method that DocumentUrlService itself uses internally to populate its cache.

This fallback was already used for the variant path, so I've also aligned that to use the DocumentUrlService when it can.

Testing

Use the NuGet packages built from this PR in a local feed. Verify that the issue no longer occurs.

AB: I've done this.

Copilot AI review requested due to automatic review settings March 24, 2026 15:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an upgrade/startup race where Examine indexing can run before DocumentUrlService is initialized, causing InvalidOperationException during value set building. The change ensures URL segments can still be produced during indexing by falling back to direct segment computation when the service cache is unavailable.

Changes:

  • Guard IDocumentUrlService.GetUrlSegment(...) calls behind IsInitialized checks during Examine value set creation.
  • Add a fallback path that computes URL segments directly from IContent when the document URL cache is not ready.
  • Use DocumentUrlService for variant URL segments when initialized (instead of always bypassing it).

@AndyButland AndyButland changed the title Examine: Fix DocumentUrlService not initialized during Examine indexing after package upgrade (closes #22230) Examine: Fix DocumentUrlService not initialized during Examine indexing after package upgrade Mar 24, 2026
@AndyButland AndyButland marked this pull request as draft March 24, 2026 15:09
@AndyButland AndyButland marked this pull request as ready for review March 24, 2026 17:20
@AndyButland AndyButland changed the title Examine: Fix DocumentUrlService not initialized during Examine indexing after package upgrade Examine: Fix DocumentUrlService not initialized during Examine indexing after package upgrade Mar 24, 2026
Copy link
Copy Markdown
Member

@Zeegaan Zeegaan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can reproduce this easily, and this pr fies it 🚀
This is pointed at main, but it's probably worth including in 17.3 🤔

@AndyButland
Copy link
Copy Markdown
Contributor Author

Thanks @Zeegaan - I agree, will cherry-pick it over.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants