stride3d/stride · error · InvalidOperationException

[{nameof(Session)}] cannot be null in {GetType().Name}

Error message

[{nameof(Session)}] cannot be null in {GetType().Name}

What it means

SessionTemplateGeneratorParameters.ValidateParameters throws this InvalidOperationException when the Session property (the PackageSession the template generator should operate on) has not been set. Stride requires a live session object for session-scoped template generation (e.g. creating a new project inside an open editor session), so it fails fast during Validate() instead of letting the generator crash later with a NullReferenceException.

Solutions

  1. Set the Session property to a valid, loaded PackageSession instance before calling Validate() or running the generator.
  2. Load or create the PackageSession first (e.g. PackageSession.Load on the solution file) and pass it into the parameters.
  3. If you do not have a session, use a template/generator parameters type whose scope does not require a session.

Example fix

// before
var p = new SessionTemplateGeneratorParameters
{
    Name = "MyGame",
    Description = templateDescription,
    Logger = logger
};
p.Validate(); // throws

// after
var session = PackageSession.Load(solutionPath, logger);
var p = new SessionTemplateGeneratorParameters
{
    Name = "MyGame",
    Description = templateDescription,
    Logger = logger,
    Session = session
};
p.Validate();
Defensive patterns

Strategy: validation

Validate before calling

if (p is SessionTemplateGeneratorParameters sp && sp.Session == null)
    throw new InvalidOperationException("SessionTemplateGeneratorParameters.Session must be set to a loaded PackageSession before Validate().");

Type guard

bool HasSession(SessionTemplateGeneratorParameters p) => p.Session is not null;

Try / catch

try { p.Validate(); }
catch (InvalidOperationException ex) when (ex.Message.Contains(nameof(SessionTemplateGeneratorParameters.Session)))
{
    // load a PackageSession and retry or report
}

Prevention

When it happens

Trigger: Calling TemplateGeneratorParameters.Validate() (which invokes ValidateParameters) on a SessionTemplateGeneratorParameters instance whose Session property is still null — typically after constructing the parameters object and setting Name/Description/Logger but forgetting to assign Session before generating a session-scope template.

Common situations: Custom tooling or editor plugins that create new projects via the template system but only partially populate the parameters; code copied from a Package/Asset template sample that doesn't set Session; running generation headlessly without loading a PackageSession first.

Related errors


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

Appendix: source

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

public sealed class SessionTemplateGeneratorParameters : TemplateGeneratorParameters
{
    /// <summary>
    /// Gets or sets the current session.
    /// </summary>
    /// <value>The session.</value>
    public PackageSession Session { get; set; }

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

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

public class PackageTemplateGeneratorParameters : TemplateGeneratorParameters
{
    public PackageTemplateGeneratorParameters()
    {
    }

    public PackageTemplateGeneratorParameters(TemplateGeneratorParameters parameters, Package package)
        : base(parameters)
    {
        Package = package;
    }
    /// <summary>
    /// Gets or sets the package in which to execute this template
    /// </summary>

View on GitHub (pinned to 96fad776d2)