LykosAI/StabilityMatrix · error · InvalidOperationException
Relative URL did not contain a route path
Error message
Relative URL did not contain a route path
What it means
BuildDetailDataPath converts a relative model URL into the Next.js data path (e.g. /models/{id}.json) and throws InvalidOperationException when the resulting URL path is empty after trimming trailing slashes — meaning the relative URL had no route component.
Solutions
- Pass a URL containing a route path, e.g. "/models/12345"
- Strip query/fragment and rebuild from the model ID if only those parts exist
- Pre-validate that the URL's path is non-empty before calling
Example fix
// before
BuildDetailDataPath("?modelVersionId=99");
// after
BuildDetailDataPath("/models/12345?modelVersionId=99"); Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrWhiteSpace(url) || !url.TrimStart('/').Split('?')[0].Split('#')[0].Contains('/')) throw new ArgumentException("URL has no route path"); Type guard
bool HasRoutePath(string? url) => !string.IsNullOrWhiteSpace(url) && new Uri(CivArchiveApiClient.BaseUri, url).AbsolutePath.TrimEnd('/').Length > 0; Try / catch
try { var path = CivArchiveApiClient.BuildDetailDataPath(url); }
catch (InvalidOperationException ex) { Logger.Warn(ex, "URL {Url} has no route path", url); return null; } Prevention
- Always pass route paths like /models/{id}, not query or fragment strings
- Normalize stored URLs on ingest
- Reuse BuildDetailDataPath's logic to validate URLs early
- Include the query string after the path, never instead of it
When it happens
Trigger: Calling BuildDetailDataPath (directly or via GetModelDetailsAsync) with a URL like "", "?query=1", or a fragment-only reference so uri.AbsolutePath resolves to "/" and trims to empty.
Common situations: Passing query-string or fragment strings instead of route paths, malformed stored URLs missing the path component, base-URI-only references.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Must have at least one image
- Unsupported Python version
- Unable to get preview image file extension from from Uri…
- URL is required
- Invalid URL format
AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12).
Data as JSON: /api/errors/4f95206d16fd09cd.
Report an issue: GitHub.
Appendix: source
Thrown at StabilityMatrix.Core/Api/CivArchiveApiClient.cs:337
{
query.Add($"type={Uri.EscapeDataString(string.Join(",", filters.Types))}");
}
if (filters.BaseModels.Count > 0)
{
query.Add($"base_model={Uri.EscapeDataString(string.Join(",", filters.BaseModels))}");
}
return $"{NormalizeRoutePath(routePath)}.json?{string.Join("&", query)}";
}
public static string BuildDetailDataPath(string relativeUrl)
{
var uri = new Uri(BaseUri, relativeUrl);
var path = uri.AbsolutePath.TrimEnd('/');
if (string.IsNullOrWhiteSpace(path))
{
throw new InvalidOperationException("Relative URL did not contain a route path");
}
// Apply Next.js rewrite rules: /{platform}/models/{id}/versions/{versionId}
// rewrites to /models/{id}?modelVersionId={versionId}&platform={platform}
var rewriteMatch = PlatformDetailRewriteRegex().Match(path);
if (rewriteMatch.Success)
{
var platform = rewriteMatch.Groups["platform"].Value;
var modelId = rewriteMatch.Groups["modelId"].Value;
var versionId = rewriteMatch.Groups["versionId"].Value;
return $"/models/{modelId}.json?modelVersionId={versionId}&platform={platform}";
}
// Also handle /{platform}/models/{id} (without version)
var platformModelMatch = PlatformModelRewriteRegex().Match(path);
if (platformModelMatch.Success)
{View on GitHub (pinned to af93d6ef57)