stride3d/stride · error · InvalidOperationException

[ . ] must be in

Error message

[{nameof(Description)}.{nameof(Description.Scope)}] must be {TemplateScope.Asset} in {GetType().Name}

What it means

AssetTemplateGeneratorParameters.ValidateParameters throws this InvalidOperationException when the template Description.Scope is not TemplateScope.Asset. Asset templates must declare Asset scope so the generator knows it creates assets inside a package; a description with Package or Session scope is a configuration mismatch and validation aborts before generation runs.

Solutions

  1. Set the Description's Scope to TemplateScope.Asset (or fix the template description file).
  2. Use the TemplateDescription that actually corresponds to the asset template being run.
  3. If the template is package-scoped, switch to PackageTemplateGeneratorParameters instead.

Example fix

// before
var desc = new TemplateDescription { Id = ..., Scope = TemplateScope.Package };
var p = new AssetTemplateGeneratorParameters(targetLocation) { Description = desc, ... };
p.Validate(); // throws

// after
var desc = new TemplateDescription { Id = ..., Scope = TemplateScope.Asset };
var p = new AssetTemplateGeneratorParameters(targetLocation) { Description = desc, ... };
p.Validate();
Defensive patterns

Strategy: validation

Validate before calling

if (p is AssetTemplateGeneratorParameters ap && ap.Description?.Scope != TemplateScope.Asset)
    throw new InvalidOperationException($"Asset template requires Scope == TemplateScope.Asset, got {ap.Description?.Scope}.");

Type guard

bool IsAssetScoped(AssetTemplateGeneratorParameters p) => p.Description?.Scope == TemplateScope.Asset;

Try / catch

try { p.Validate(); }
catch (InvalidOperationException ex) when (ex.Message.Contains(nameof(TemplateDescription.Scope)))
{
    // correct the description's Scope or switch parameters type
}

Prevention

When it happens

Trigger: Calling Validate() on an AssetTemplateGeneratorParameters instance whose Description comes from a template description with Scope set to Package or Session — e.g. reusing a package template's TemplateDescription with asset parameters.

Common situations: Wiring a custom asset generator to the wrong .sdtpl description file; editing a template description's Scope field by hand and leaving it as Package; programmatically building a TemplateDescription and forgetting to set Scope = TemplateScope.Asset.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at sources/assets/Stride.Core.Assets/Templates/TemplateGeneratorParameters.cs:90

    }

    public UDirectory TargetLocation { get; }

    public List<UFile> SourceFiles { get; }

    /// <summary>
    /// Indicates whether the session has to be saved after the asset template generator has completed. The default is <c>false</c>.
    /// </summary>
    /// <remarks>This is an out parameter that asset template generator should set if needed.</remarks>
    public bool RequestSessionSave { get; set; } = false;

    protected override void ValidateParameters()
    {
        base.ValidateParameters();

        if (Description.Scope != TemplateScope.Asset)
        {
            throw new InvalidOperationException($"[{nameof(Description)}.{nameof(Description.Scope)}] must be {TemplateScope.Asset} in {GetType().Name}");
        }
        if (Package == null)
        {
            throw new InvalidOperationException($"[{nameof(Package)}] cannot be null in {GetType().Name}");
        }
    }
}

/// <summary>
/// Parameters used by <see cref="ITemplateGenerator{TParameters}"/>
/// </summary>
public abstract class TemplateGeneratorParameters
{
    protected TemplateGeneratorParameters()
    {
    }

    protected TemplateGeneratorParameters(TemplateGeneratorParameters parameters)

View on GitHub (pinned to 96fad776d2)