Skip to content

Relationship Diagnostics

Capell can emit focused diagnostics when a page URL cannot resolve the active site domain needed to build PageUrl::full_url.

Use this when errors look like:

Capell\Core\Exceptions\UrlMissingSiteDomainException
Site domain not found for page ID ..., site ID ..., and language ID ...

This diagnostic is disabled by default. It only logs when PageUrl::full_url is already about to throw, so enabling it does not change URL resolution or hide missing data.

Set this in the host app:

CAPELL_RELATIONSHIP_DIAGNOSTICS=true

Then reproduce the failing request and inspect the Laravel log:

Terminal window
grep "Capell PageUrl full_url could not resolve an active site domain" storage/logs/laravel.log

Turn the flag off after the incident. The log context includes model IDs, route details, and relationship state that are useful for debugging but too noisy for normal production logs.

The log entry is written at warning level with structured context from DiagnosePageUrlSiteDomainAction.

Key fields:

FieldMeaning
page_url_idThe page_urls.id being rendered.
pageable_type, pageable_idThe owning content record, usually a page.
site_id, language_idComposite keys used by PageUrl::siteDomain().
site_domain_relation_loadedWhether Eloquent had already loaded the siteDomain relation.
loaded_site_domain_is_nullWhether the loaded relation was explicitly null.
active_site_domain_existsWhether an active, non-deleted matching site_domains row exists.
active_site_domain_idMatching active domain ID, when present.
trashed_site_domain_existsWhether a soft-deleted matching domain exists.
trashed_site_domain_idMatching soft-deleted domain ID, when present.
trashed_site_domain_deleted_atDeletion timestamp for the matching soft-deleted domain, when present.
route_name, request_pathRequest that triggered the failing URL render.
callerFirst useful non-framework caller found in the backtrace.

If active_site_domain_exists is false and trashed_site_domain_exists is true, the page URL points at a language/site pair whose domain was soft-deleted. Restore or recreate the site_domains row, or remove/update the affected page_urls row.

If site_domain_relation_loaded is true and loaded_site_domain_is_null is true while active_site_domain_exists is also true, look for a relationship load that selected too few columns or used incompatible constraints. Composite relationships need both site_id and language_id on the parent and related models.

If both active and trashed domain checks are false, inspect the site’s language setup. The page URL may have been created for a language that no longer has a domain for that site.

Use the IDs from the log entry:

select id, pageable_type, pageable_id, site_id, language_id, url, deleted_at
from page_urls
where id = ?;
select id, site_id, language_id, domain, path, scheme, status, deleted_at
from site_domains
where site_id = ? and language_id = ?
order by deleted_at is null desc, id desc;

For admin table failures, check any VisitUrlAction or table column that calls full_url. Admin surfaces should not render an open/visit link unless the selected PageUrl has an active SiteDomain.