stride3d/stride · error · Exception
: could not set entry point
Error message
{cross.CompilerSetEntryPoint(compiler, entryPoint.Value.RealName, entryPoint.Value.ExecutionModel)} : could not set entry point What it means
Translate throws this when CompilerSetEntryPoint fails to select the requested entry point on the compiler. spirv-cross returns failure when the named entry point does not exist in the module or the ExecutionModel does not match the module's declared model for that name.
Solutions
- Call GetEntryPoints first and verify the desired RealName/ExecutionModel pair exists before passing it to Translate
- Re-fetch entry points whenever the shader module is recompiled instead of caching names
- Check name spelling/case exactly matches the SPIR-V OpEntryPoint name
- Confirm the ExecutionModel comes from the same module's entry-point list
- Pass null entryPoint to translate the default entry point and compare results
Example fix
// before
var hlsl = translator.Translate(Backend.Hlsl, ("mainPS", "main", ExecutionModel.Fragment));
// after
var eps = translator.GetEntryPoints(Backend.Hlsl);
var ep = eps.FirstOrDefault(e => e.RealName == "mainPS")
?? throw new InvalidOperationException($"Entry point 'mainPS' not found. Available: {string.Join(", ", eps.Select(e => e.RealName))}");
var hlsl = translator.Translate(Backend.Hlsl, (ep.RealName, "main", ep.ExecutionModel)); Defensive patterns
Strategy: validation
Validate before calling
var available = translator.GetEntryPoints(backend);
if (entryPoint != null && !available.Any(e => e.RealName == entryPoint.Value.RealName && e.ExecutionModel == entryPoint.Value.ExecutionModel))
throw new InvalidOperationException($"Entry point '{entryPoint.Value.RealName}' ({entryPoint.Value.ExecutionModel}) not in module"); Try / catch
try { var src = translator.Translate(backend, entryPoint); } catch (Exception ex) when (ex.Message.Contains("could not set entry point")) { Log.Error($"Entry point '{entryPoint?.RealName}' invalid; available: {string.Join(", ", translator.GetEntryPoints(backend).Select(e => e.RealName))}"); throw; } Prevention
- Always derive entry points from GetEntryPoints on the same Words buffer being translated
- Never cache entry-point names across shader recompilations
- Match names case-sensitively
- Pair RealName with its ExecutionModel from the same list entry
When it happens
Trigger: Calling Translate(backend, entryPoint) with a RealName that is not an entry point in the SPIR-V (e.g. stale name after shader recompilation/renaming), or an ExecutionModel that disagrees with the module (e.g. passing Vertex for a fragment shader).
Common situations: Caching entry-point names from a previous shader version and reusing them after the effect was recompiled; mixing entry points across shader stages; case-sensitivity mistakes in the entry point name; getting names from a different SPIR-V module than the one being translated.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- : could not create compiler
- : could not compile code
- Invalid type [ ]. Type must be assignable to Asset
- Expected STREAM-START.
- The given source panel is not a root element of this asset.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/81aa6a7242e78d4b.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs:110
// RenderDoc's shader viewer when displaying the cross-compiled HLSL/GLSL.
// OpLine in the SPIR-V is preserved for Vulkan/RenderDoc callstacks.
cross.CompilerOptionsSetBool(compilerOptions, CompilerOption.EmitLineDirectives, 0);
if (backend == Backend.Hlsl)
{
cross.CompilerOptionsSetUint(compilerOptions, CompilerOption.HlslShaderModel, 50);
cross.CompilerOptionsSetBool(compilerOptions, CompilerOption.HlslPreserveStructuredBuffers, 1);
// FXC rejects uninitialized loop-carried variables (from OpUndef phi inputs) with a
// bogus "error X4555: cannot use casts on l-values" when they end up assigned in a
// for-loop continue expression.
cross.CompilerOptionsSetBool(compilerOptions, CompilerOption.ForceZeroInitializedVariables, 1);
}
cross.CompilerInstallCompilerOptions(compiler, compilerOptions);
}
if (entryPoint != null)
{
if (cross.CompilerSetEntryPoint(compiler, entryPoint.Value.RealName, entryPoint.Value.ExecutionModel) != Result.Success)
throw new Exception($"{cross.CompilerSetEntryPoint(compiler, entryPoint.Value.RealName, entryPoint.Value.ExecutionModel)} : could not set entry point");
}
if (cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success)
throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources");
// HLSL: remove type_ prefix from cbuffer (they get names from struct instead of cbuffer variable itself)
if (backend == Backend.Hlsl)
{
ReflectedResource* resourcesList;
nuint resourcesCount;
cross.ResourcesGetResourceListForType(resources, ResourceType.UniformBuffer, &resourcesList, &resourcesCount);
for (uint i = 0; i < resourcesCount; ++i)
{
var resource = resourcesList[i];
var cbufferName = Marshal.PtrToStringAnsi((IntPtr)resource.Name)!;
if (cbufferName.StartsWith("type."))
{View on GitHub (pinned to 96fad776d2)