stride3d/stride · error · SolutionFileException

Unsupported solution file format

Error message

Unsupported solution file format: '{solutionFullPath}'.

What it means

Thrown by SolutionSerialization.Read when no registered serializer moniker matches the given file's extension/format. The path does not look like a .sln, .slnf, or other supported solution format the library can open.

Solutions

  1. Pass a supported solution file (.sln or .slnf) path to Read
  2. Verify the file extension is correct and the file exists at that path
  3. If using a custom format, register a matching serializer moniker in SolutionSerializers

Example fix

// before
var solution = SolutionSerialization.Read(@"C:\repo\MyApp\MyApp.csproj");
// after
var solution = SolutionSerialization.Read(@"C:\repo\MyApp\MyApp.sln");
Defensive patterns

Strategy: validation

Validate before calling

var ext = Path.GetExtension(path);
if (!ext.Equals(".sln", StringComparison.OrdinalIgnoreCase) &&
    !ext.Equals(".slnf", StringComparison.OrdinalIgnoreCase))
    throw new ArgumentException($"Expected a .sln or .slnf file, got '{ext}'");

Type guard

bool IsSupportedSolutionFile(string p) =>
    Path.GetExtension(p) is ".sln" or ".slnf";

Try / catch

try { return SolutionSerialization.Read(path); }
catch (SolutionFileException ex) when (ex.Message.StartsWith("Unsupported solution file format"))
{
    throw new ArgumentException($"'{path}' is not a supported solution file", nameof(path), ex);
}

Prevention

When it happens

Trigger: Calling Read (or Solution.Open) with a path whose extension does not match any serializer registered in SolutionSerializers — e.g. passing a .csproj, .txt, or an unknown extension instead of a .sln/.slnf file.

Common situations: Passing the wrong file to the solution loader, using a custom solution format not registered, typos in the file extension.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/3551fcb6a8740926. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.Design/Solutions/SolutionSerialization.cs:31

/// mapping between its model and the <see cref="Solution"/> model used by the asset pipeline.
/// </summary>
internal static class SolutionSerialization
{
    // A solution created from scratch gets a single Any CPU platform and Debug/Release build types;
    // SolutionPersistence generates the per-project configuration mappings from these. A solution loaded
    // from disk keeps whatever it already had (see Write).
    private const string DefaultPlatform = "Any CPU";
    private static readonly string[] DefaultBuildTypes = ["Debug", "Release"];

    public static Solution Read(string solutionFullPath)
    {
        // A .slnf solution filter is JSON pointing at a real .sln; open the underlying solution so edits
        // persist to it (the filter is a view, not a writable solution).
        if (Path.GetExtension(solutionFullPath).Equals(".slnf", StringComparison.OrdinalIgnoreCase))
            return Read(ResolveSolutionFilterTarget(solutionFullPath));

        var serializer = SolutionSerializers.GetSerializerByMoniker(solutionFullPath)
            ?? 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.");

View on GitHub (pinned to 96fad776d2)