{"record":{"id":"936d319f9b2f1331","repo":"stride3d/stride","slug":"samplerstate-name-already-defined","errorCode":null,"errorMessage":"SamplerState {Name} already defined","messagePattern":"SamplerState (.+?) already defined","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs","lineNumber":57,"sourceCode":"    public Symbol? Symbol { get; private set; }\n\n    public override void ProcessSymbol(SymbolTable table, SpirvContext context)\n    {\n        base.ProcessSymbol(table, context);\n        Type = new PointerType(new SamplerType(), Specification.StorageClass.UniformConstant);\n        table.DeclaredTypes.TryAdd(Type.ToString(), Type);\n\n        var sid = new SymbolID(Name, SymbolKind.SamplerState);\n        Symbol = new Symbol(sid, Type, 0, OwnerType: table.CurrentShader);\n        table.CurrentShader!.Variables.Add((Symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None));\n    }\n\n    public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler)\n    {\n        (var builder, var context) = compiler;\n        var registeredType = context.GetOrRegister(Type);\n        if (table.RootSymbols.TryGetValue(Name, out _))\n            throw new Exception($\"SamplerState {Name} already defined\");\n\n        var variableId = context.Bound++;\n\n        // Encode all sampler state fields into a single OpDecorate\n        // Defaults match SamplerStateDescription.Default: Linear(21) filter, Clamp(3) addressing, no LOD bias, 16x aniso, Never(1) compare, full LOD range\n        int filter = 21; // TextureFilter.Linear = MIN_MAG_MIP_LINEAR\n        int addressU = (int)Specification.SamplerTextureAddressModeSDSL.Clamp;\n        int addressV = (int)Specification.SamplerTextureAddressModeSDSL.Clamp;\n        int addressW = (int)Specification.SamplerTextureAddressModeSDSL.Clamp;\n        int mipLODBias = 0; // BitConverter.SingleToInt32Bits(0.0f) == 0\n        int maxAnisotropy = 16;\n        int comparisonFunc = (int)Specification.SamplerComparisonFuncSDSL.Never;\n        int minLOD = BitConverter.SingleToInt32Bits(-float.MaxValue);\n        int maxLOD = BitConverter.SingleToInt32Bits(float.MaxValue);\n        int borderR = 0, borderG = 0, borderB = 0, borderA = 0; // Black (0,0,0,0)\n        foreach (var parameter in Parameters)\n        {\n            switch (parameter.Name)","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs#L39-L75","documentation":"Thrown when compiling a SamplerState member whose Name is already present in the symbol table's RootSymbols, i.e. a duplicate sampler state declaration. Each sampler state name must be unique at the shader root level because it becomes a distinct decorated variable.","triggerScenarios":"Declaring two SamplerState members with the same name in one shader; inheriting/mixin-combining shaders that each declare a SamplerState with the same name; a compose mixin bringing in a sampler that clashes with a locally declared one.","commonSituations":"Mixin composition where a base shader and an added mixin both define e.g. 'LinearClampSampler'; copy-pasted sampler declarations; renaming a shader but leaving a duplicate sampler behind.","solutions":["Rename one of the conflicting SamplerState declarations","Remove the redundant sampler if it duplicates an inherited/composed one","Use mixin overriding semantics intentionally instead of re-declaring the same name"],"exampleFix":"// before\nSamplerState LinearClampSampler; // also declared in inherited shader\nSamplerState LinearClampSampler; // duplicate\n// after\nSamplerState LinearClampSampler;\nSamplerState LinearWrapSampler;","handlingStrategy":"validation","validationCode":"if (table.RootSymbols.ContainsKey(sampler.Name))\n    throw new InvalidOperationException($\"SamplerState {sampler.Name} already defined\");","typeGuard":"bool IsUniqueName(string name, SymbolTable t) => !t.RootSymbols.ContainsKey(name);","tryCatchPattern":"try { samplerState.Compile(table, shader, compiler); }\ncatch (Exception ex) { table.AddError(new(info, ex.Message)); }","preventionTips":["Give samplers unique names across base shaders and mixins","Review mixin composition for name collisions","Check RootSymbols before declaring new members"],"tags":["sdsl","duplicate-definition","sampler-state"],"backgroundTag":"file-already-exists","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}