{"record":{"id":"00a07935f96d9a0e","repo":"LykosAI/StabilityMatrix","slug":"civarchive-detail-page-was-missing-pageprops","errorCode":null,"errorMessage":"CivArchive detail page was missing pageProps","messagePattern":"CivArchive detail page was missing pageProps","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Core/Api/CivArchiveApiClient.cs","lineNumber":180,"sourceCode":"    )\n    {\n        if (string.IsNullOrWhiteSpace(relativeUrl))\n        {\n            throw new ArgumentException(\"Relative URL is required\", nameof(relativeUrl));\n        }\n\n        var nextDataPath = BuildDetailDataPath(relativeUrl);\n\n        if (detailsCache.Get(nextDataPath) is { } cachedDetails && cachedDetails.IsFresh(DetailsCacheTtl))\n        {\n            return cachedDetails.Value;\n        }\n\n        var response = await GetNextDataAsync<CivArchiveDetailPageResponse>(nextDataPath, cancellationToken);\n\n        var pageProps =\n            response.PageProps\n            ?? throw new InvalidOperationException(\"CivArchive detail page was missing pageProps\");\n\n        // A version-less /models/{id} data request returns a Next.js redirect payload pointing\n        // at the model's primary version instead of pageProps.model — follow it like the\n        // browser would. Guarded against self-redirects so a server quirk can't loop us.\n        if (\n            pageProps.Model is null\n            && !string.IsNullOrWhiteSpace(pageProps.RedirectUrl)\n            && BuildDetailDataPath(pageProps.RedirectUrl) != nextDataPath\n        )\n        {\n            var redirected = await GetModelDetailsAsync(pageProps.RedirectUrl, cancellationToken);\n            detailsCache.Add(\n                nextDataPath,\n                new CacheEntry<CivArchiveModelDetailsResponse>(DateTimeOffset.UtcNow, redirected)\n            );\n            return redirected;\n        }\n","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Core/Api/CivArchiveApiClient.cs#L162-L198","documentation":"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.","triggerScenarios":"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.","commonSituations":"Deleted or renamed model routes on CivArchive, site redesign changing the Next.js data contract, anti-bot challenge pages replacing real content.","solutions":["Verify the URL in a browser to see whether the model page still exists","Update the client's response models to match the current site schema","Retry later if the site is temporarily degraded","Cache last-known-good details as a fallback"],"exampleFix":"// before\nvar pageProps = response.PageProps ?? throw new InvalidOperationException(\"CivArchive detail page was missing pageProps\");\n// after\nif (response.PageProps?.Model is null) throw new CivitaiModelNotFoundException(url);","handlingStrategy":"try-catch","validationCode":"var details = await cache.GetOrCreateAsync(key, ...); // check cached presence before fetching\nbool urlLooksLikeModel = Regex.IsMatch(url, @\"^/models/[^/?]+\");","typeGuard":"bool HasModel(CivArchiveDetailPageResponse r) => r?.PageProps?.Model is not null;","tryCatchPattern":"try { return await api.GetModelDetailsAsync(url); }\ncatch (InvalidOperationException) { return staleCachedDetails; /* mark stale */ }","preventionTips":["Fall back to cached details when live fetch lacks a model","Verify URLs still resolve after site changes","Retry with backoff before declaring the model gone","Alert on repeated pageProps-shape failures"],"tags":["scraping","nextjs","api","upstream"],"backgroundTag":"unexpected-response-shape","analyzedSha":"af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002","analyzedAt":"2026-09-12T19:02:43.389Z","contentChangedAt":"2026-09-12T19:02:43.389Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}