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\UrlMissingSiteDomainExceptionSite 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.
Enable Diagnostics
Section titled “Enable Diagnostics”Set this in the host app:
CAPELL_RELATIONSHIP_DIAGNOSTICS=trueThen reproduce the failing request and inspect the Laravel log:
grep "Capell PageUrl full_url could not resolve an active site domain" storage/logs/laravel.logTurn 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.
What Gets Logged
Section titled “What Gets Logged”The log entry is written at warning level with structured context from DiagnosePageUrlSiteDomainAction.
Key fields:
| Field | Meaning |
|---|---|
page_url_id | The page_urls.id being rendered. |
pageable_type, pageable_id | The owning content record, usually a page. |
site_id, language_id | Composite keys used by PageUrl::siteDomain(). |
site_domain_relation_loaded | Whether Eloquent had already loaded the siteDomain relation. |
loaded_site_domain_is_null | Whether the loaded relation was explicitly null. |
active_site_domain_exists | Whether an active, non-deleted matching site_domains row exists. |
active_site_domain_id | Matching active domain ID, when present. |
trashed_site_domain_exists | Whether a soft-deleted matching domain exists. |
trashed_site_domain_id | Matching soft-deleted domain ID, when present. |
trashed_site_domain_deleted_at | Deletion timestamp for the matching soft-deleted domain, when present. |
route_name, request_path | Request that triggered the failing URL render. |
caller | First useful non-framework caller found in the backtrace. |
Interpreting Results
Section titled “Interpreting Results”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.
Common Checks
Section titled “Common Checks”Use the IDs from the log entry:
select id, pageable_type, pageable_id, site_id, language_id, url, deleted_atfrom page_urlswhere id = ?;
select id, site_id, language_id, domain, path, scheme, status, deleted_atfrom site_domainswhere 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.