stride3d/stride · error · SolutionFileException
Solution filter ' ' does not reference a solution.
Error message
Solution filter '{filterFile}' does not reference a solution. What it means
Thrown by ResolveSolutionFilterTarget when a .slnf solution-filter file parses as JSON but lacks the expected 'solution.path' property. A .slnf must point at a real .sln via solution.path for the library to open the underlying writable solution.
Solutions
- Open the .slnf in an editor and ensure it contains a top-level "solution": { "path": "..." } property
- Point 'path' at the correct .sln relative to the .slnf file's directory
- Regenerate the solution filter in Visual Studio/IDE instead of hand-editing
Example fix
// before (broken .slnf)
{ "projects": ["src\\App\\App.csproj"] }
// after
{ "solution": { "path": "MyApp.sln" }, "projects": ["src\\App\\App.csproj"] } Defensive patterns
Strategy: validation
Validate before calling
using var doc = JsonDocument.Parse(File.ReadAllText(filterPath));
if (!doc.RootElement.TryGetProperty("solution", out var s) ||
!s.TryGetProperty("path", out _))
throw new InvalidDataException($"{filterPath} has no solution.path"); Type guard
bool IsValidFilter(string json) =>
JsonDocument.Parse(json).RootElement.TryGetProperty("solution", out var s) &&
s.TryGetProperty("path", out var p) && p.ValueKind == JsonValueKind.String; Try / catch
try { return SolutionSerialization.Read(filterPath); }
catch (SolutionFileException ex) when (ex.Message.Contains("does not reference a solution"))
{
throw new InvalidDataException($"Filter '{filterPath}' is missing 'solution.path'", ex);
} Prevention
- Never hand-edit .slnf files; regenerate them in the IDE
- Validate the .slnf JSON schema before loading
- Ensure the referenced .sln path resolves relative to the filter file
When it happens
Trigger: Calling Read with a .slnf file whose JSON root object is missing the 'solution' property or whose 'solution.path' string is absent/null — e.g. a hand-edited or corrupted filter file.
Common situations: Manually authored .slnf with wrong schema, filter files saved by tools with different casing, truncated/corrupted JSON filters.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/9c8d27da38538a35.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.Design/Solutions/SolutionSerialization.cs:49
?? throw new SolutionFileException($"Unsupported solution file format: '{solutionFullPath}'.");
var model = serializer.OpenAsync(solutionFullPath, CancellationToken.None).GetAwaiter().GetResult();
var solution = ToSolution(model, solutionFullPath);
ReadDefaultStartup(solution, solutionFullPath);
return solution;
}
// The .sln a solution filter (.slnf) points at, resolved relative to the filter file.
private static string ResolveSolutionFilterTarget(string filterFile)
{
using var document = JsonDocument.Parse(File.ReadAllText(filterFile));
if (document.RootElement.TryGetProperty("solution", out var solution)
&& solution.TryGetProperty("path", out var path)
&& path.GetString() is { } relativePath)
{
return Path.GetFullPath(Path.Combine(Path.GetDirectoryName(filterFile)!, relativePath.Replace('\\', Path.DirectorySeparatorChar)));
}
throw new SolutionFileException($"Solution filter '{filterFile}' does not reference a solution.");
}
public static Solution Read(string solutionFullPath, Stream stream)
{
var model = SolutionSerializers.SlnFileV12.OpenAsync(stream, CancellationToken.None).GetAwaiter().GetResult();
return ToSolution(model, solutionFullPath);
}
public static void Write(Solution solution, string outputPath, Action<string>? onBeforeOverwrite = null)
{
// Behave like Visual Studio: a solution loaded from disk keeps everything it had (platforms, build
// configurations, solution folders, projects Stride doesn't manage) and only its project list is
// reconciled. A solution that wasn't loaded from disk is created from a fresh model with defaults.
var model = solution.SourceModel is { } source ? new SolutionModel(source) : NewModel(solution);
Reconcile(model, solution, outputPath);
// Pick the serializer from the output extension so a .slnx round-trips as XML and a .sln as classic format.
var serializer = SolutionSerializers.GetSerializerByMoniker(outputPath) ?? SolutionSerializers.SlnFileV12;View on GitHub (pinned to 96fad776d2)