stride3d/stride · error · InvalidOperationException

string.Join(Environment.NewLine, loggerResult.Messages.Where

Error message

string.Join(Environment.NewLine, loggerResult.Messages.Where(m => m.Type >= LogMessageType.Error).Select(m => m.ToString()))

What it means

In ShaderLoaderBase.LoadFromCode, the SDSLC compile is invoked with a caller-provided or temporary LoggerResult. When compilation fails and that logger actually recorded error-level messages, the loader throws InvalidOperationException whose message is the newline-joined text of all messages with Type >= LogMessageType.Error — i.e. the real compiler diagnostics. If the logger has no recorded errors it returns false instead, so this throw always carries concrete compile output.

Solutions

  1. Read the exception message: it contains each compiler error line; fix the offending .sdsl source at the reported positions.
  2. Check for recent edits to the shader and its included/composed sources.
  3. Verify macros/defines passed in don't enable conflicting code paths that fail to compile.
  4. Re-run compilation after fixing; clear the shader cache so a failed buffer is not reused.

Example fix

// before (SDSL)
stage float4 main() { return float4(1,0,0; } // missing ')' -> compile error
// after
stage float4 main() { return float4(1,0,0); }
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-lint the SDSL source with the same macros in a scratch LoggerResult
var pre = new LoggerResult();
sdslc.Compile(filename, text, hash, macros, pre, out _, new() { RegisterInCache = false });
bool compiles = !pre.HasErrors;

Try / catch

try { loader.LoadFromCode(filename, text, hash, macros, out var buffer); }
catch (InvalidOperationException ex)
{
    // message contains joined compiler errors
    foreach (var line in ex.Message.Split(Environment.NewLine))
        Console.Error.WriteLine(line);
}

Prevention

When it happens

Trigger: sdslc.Compile returns false with RegisterInCache/EmitSourceHash options and the loggerResult.HasErrors is true — i.e. any SDSL compile error (parse, semantic, macro expansion) during LoadFromCode.

Common situations: Editing .sdsl files with syntax errors; invalid keyword/annotation usage; shader referencing missing mixins or types; macro combinations that generate invalid code.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs:183

    protected virtual bool LoadFromCode(string? filename, string code, ObjectId hash, ReadOnlySpan<ShaderMacro> macros, out ShaderBuffers buffer, bool registerInCache = true, bool emitSourceHash = true)
    {
        var defines = new (string Name, string Definition)[macros.Length];
        for (int i = 0; i < macros.Length; ++i)
            defines[i] = (macros[i].Name, macros[i].Definition);

        var text = MonoGamePreProcessor.Run(code, filename, defines);
        var sdslc = new SDSLC
        {
            ShaderLoader = this,
        };

        // Use provided logger, or a temporary one that throws on errors
        var log = Log ?? new LoggerResult();
        if (!sdslc.Compile(filename, text, hash, macros, log, out buffer, new() { RegisterInCache = registerInCache, EmitSourceHash = emitSourceHash, OriginalCode = code }))
        {
            if (log is LoggerResult loggerResult && loggerResult.HasErrors)
                throw new InvalidOperationException(string.Join(Environment.NewLine, loggerResult.Messages.Where(m => m.Type >= LogMessageType.Error).Select(m => m.ToString())));
            return false;
        }
        return true;
    }
}

View on GitHub (pinned to 96fad776d2)