LykosAI/StabilityMatrix · error · InvalidOperationException

CivArchive detail page was missing pageProps

Error message

CivArchive detail page was missing pageProps

What it means

GetModelDetailsAsync throws InvalidOperationException when the __NEXT_DATA__ payload of the CivArchive detail page contains no PageProps. Without pageProps there is no model payload to deserialize, so the client cannot return model details.

Solutions

  1. Verify the URL in a browser to see whether the model page still exists
  2. Update the client's response models to match the current site schema
  3. Retry later if the site is temporarily degraded
  4. Cache last-known-good details as a fallback

Example fix

// before
var pageProps = response.PageProps ?? throw new InvalidOperationException("CivArchive detail page was missing pageProps");
// after
if (response.PageProps?.Model is null) throw new CivitaiModelNotFoundException(url);
Defensive patterns

Strategy: try-catch

Validate before calling

var details = await cache.GetOrCreateAsync(key, ...); // check cached presence before fetching
bool urlLooksLikeModel = Regex.IsMatch(url, @"^/models/[^/?]+");

Type guard

bool HasModel(CivArchiveDetailPageResponse r) => r?.PageProps?.Model is not null;

Try / catch

try { return await api.GetModelDetailsAsync(url); }
catch (InvalidOperationException) { return staleCachedDetails; /* mark stale */ }

Prevention

When it happens

Trigger: Calling GetModelDetailsAsync when the detail page's Next.js data lacks pageProps — site layout change, error/redirect HTML served instead of the model page, or a removed/deleted model route.

Common situations: Deleted or renamed model routes on CivArchive, site redesign changing the Next.js data contract, anti-bot challenge pages replacing real content.

Related errors


AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12). Data as JSON: /api/errors/00a07935f96d9a0e. Report an issue: GitHub.

Appendix: source

Thrown at StabilityMatrix.Core/Api/CivArchiveApiClient.cs:180

    )
    {
        if (string.IsNullOrWhiteSpace(relativeUrl))
        {
            throw new ArgumentException("Relative URL is required", nameof(relativeUrl));
        }

        var nextDataPath = BuildDetailDataPath(relativeUrl);

        if (detailsCache.Get(nextDataPath) is { } cachedDetails && cachedDetails.IsFresh(DetailsCacheTtl))
        {
            return cachedDetails.Value;
        }

        var response = await GetNextDataAsync<CivArchiveDetailPageResponse>(nextDataPath, cancellationToken);

        var pageProps =
            response.PageProps
            ?? throw new InvalidOperationException("CivArchive detail page was missing pageProps");

        // A version-less /models/{id} data request returns a Next.js redirect payload pointing
        // at the model's primary version instead of pageProps.model — follow it like the
        // browser would. Guarded against self-redirects so a server quirk can't loop us.
        if (
            pageProps.Model is null
            && !string.IsNullOrWhiteSpace(pageProps.RedirectUrl)
            && BuildDetailDataPath(pageProps.RedirectUrl) != nextDataPath
        )
        {
            var redirected = await GetModelDetailsAsync(pageProps.RedirectUrl, cancellationToken);
            detailsCache.Add(
                nextDataPath,
                new CacheEntry<CivArchiveModelDetailsResponse>(DateTimeOffset.UtcNow, redirected)
            );
            return redirected;
        }

View on GitHub (pinned to af93d6ef57)