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
- Read the exception message: it contains each compiler error line; fix the offending .sdsl source at the reported positions.
- Check for recent edits to the shader and its included/composed sources.
- Verify macros/defines passed in don't enable conflicting code paths that fail to compile.
- 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
- Parse the exception message — it lists every error with file/line.
- Keep a compile-check step in CI for all .sdsl sources.
- Clear the shader cache after compiler upgrades so stale failures don't persist.
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
- Shader {name} could not be compiled
- Invalid Shader stage specified in the Effect bytecode.
- Vulkan: bytecode is expected to be the same for all stages
- antialiasShaderName
- colorTransformShader
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)