stride3d/stride · error · KeyNotFoundException

Tag not found in template generator parameters

Error message

Tag not found in template generator parameters

What it means

TemplateGeneratorParameters.GetTag<T> throws this KeyNotFoundException when the requested PropertyKey<T> has no value stored in the parameters' Tags PropertyContainer. GetTag is the strict accessor (unlike TryGetTag which returns the default); it is meant for generators that require the tag to be present, so a missing key is surfaced as an exception.

Solutions

  1. Set the tag before running the generator: parameters.SetTag(key, value).
  2. If the tag is optional, switch to TryGetTag(key) or HasTag(key) instead of GetTag.
  3. Verify you are using the exact same PropertyKey<T> instance that was used with SetTag (keys are compared by identity/equality).

Example fix

// before
var outputDir = parameters.GetTag(TemplateGeneratorTags.OutputDir); // may throw

// after
if (parameters.HasTag(TemplateGeneratorTags.OutputDir))
{
    var outputDir = parameters.GetTag(TemplateGeneratorTags.OutputDir);
}
else
{
    var outputDir = parameters.TryGetTag(TemplateGeneratorTags.OutputDir); // default
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (key != null && !parameters.HasTag(key))
    throw new InvalidOperationException($"Required tag '{key.Name}' was not set on template generator parameters.");

Type guard

bool HasRequiredTag<T>(TemplateGeneratorParameters p, PropertyKey<T> key) => p.HasTag(key);

Try / catch

try { value = parameters.GetTag(key); }
catch (KeyNotFoundException)
{
    value = parameters.TryGetTag(key); // fall back to default
    // or log which required tag was missing
}

Prevention

When it happens

Trigger: Calling parameters.GetTag(somePropertyKey) where SetTag was never called for that key on this parameters instance (or a copied parameters object didn't carry the tag).

Common situations: A custom template generator reading an optional tag that the caller never set; invoking a generator programmatically without the tags the editor normally injects; using a different PropertyKey instance/key than the one that was set; tag set on the original parameters but lost when constructing a new parameters object.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

    /// Validates this instance (all fields must be setup)
    /// </summary>
    public void Validate()
    {
        ValidateParameters();
    }

    /// <summary>
    /// Gets the tag corresponding to the given property key. This will fail if key doesn't exist.
    /// </summary>
    /// <typeparam name="T">The generic type of the property key.</typeparam>
    /// <param name="key">The property key for which to retrieve the value.</param>
    /// <returns>The value of the tag corresponding to the given property key.</returns>
    /// <exception cref="KeyNotFoundException">Tag not found in template generator parameters.</exception>
    public T GetTag<T>(PropertyKey<T> key)
    {
        if (!Tags.TryGetValue(key, out var result))
        {
            throw new KeyNotFoundException("Tag not found in template generator parameters");
        }
        return result;
    }

    /// <summary>
    /// Gets the tag corresponding to the given property key if available, otherwise returns default value.
    /// </summary>
    /// <typeparam name="T">The generic type of the property key.</typeparam>
    /// <param name="key">The property key for which to retrieve the value.</param>
    /// <returns>The value of the tag corresponding to the given property key if available, the default value of the property key otherwise.</returns>
    public T? TryGetTag<T>(PropertyKey<T> key)
    {
        return Tags.Get(key);
    }

    /// <summary>
    /// 
    /// </summary>

View on GitHub (pinned to 96fad776d2)