microsoft/semantic-kernel · error · ArgumentException

The template could not be parsed:{Environment.NewLine}{error

Error message

The template could not be parsed:{Environment.NewLine}{error}

What it means

Thrown by the LiquidPromptTemplate constructor when `s_parser.TryParse` returns false during eager parsing. The parser runs at construction time so syntax errors surface immediately; the message includes the parser's `error` detail when available, otherwise a generic parse-failure string.

Source

Thrown at dotnet/src/Extensions/PromptTemplates.Liquid/LiquidPromptTemplate.cs:65

    /// <exception cref="ArgumentNullException">throw if <paramref name="config"/> is null</exception>
    /// <exception cref="ArgumentNullException">throw if the template in <paramref name="config"/> is null</exception>
    public LiquidPromptTemplate(PromptTemplateConfig config, bool allowDangerouslySetContent = false)
    {
        Verify.NotNull(config, nameof(config));
        Verify.NotNull(config.Template, nameof(config.Template));
        if (config.TemplateFormat != LiquidPromptTemplateFactory.LiquidTemplateFormat)
        {
            throw new ArgumentException($"Invalid template format: {config.TemplateFormat}");
        }

        this._allowDangerouslySetContent = allowDangerouslySetContent;
        this._config = config;

        // Parse the template now so we can check for errors, understand variable usage, and
        // avoid having to parse on each render.
        if (!s_parser.TryParse(config.Template, out this._liquidTemplate, out string error))
        {
            throw new ArgumentException(error is not null ?
                $"The template could not be parsed:{Environment.NewLine}{error}" :
                 "The template could not be parsed.");
        }

        // Ideally the prompty author would have explicitly specified input variables. If they specified any,
        // assume they specified them all. If they didn't, heuristically try to find the variables, looking for
        // variables that are read but never written and that appear to be simple values rather than complex objects.
        if (config.InputVariables.Count == 0)
        {
            foreach (string implicitVariable in SimpleVariablesVisitor.InferInputs(this._liquidTemplate))
            {
                config.InputVariables.Add(new() { Name = implicitVariable, AllowDangerouslySetContent = config.AllowDangerouslySetContent });
            }
        }

        // Configure _inputVariables with the default values from the config. This will be used
        // in RenderAsync to seed the arguments used when evaluating the template.
        this._inputVariables = [];

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Read the embedded `error` string — it names the offending line/token.
  2. Validate the template in a standalone Liquid/FFluid playground first.
  3. Balance all `{% %}` blocks (if/unless/for/case each need a matching end tag).

Example fix

// before
{% if active %}Hello{% end %}
// after
{% if active %}Hello{% endif %}
Defensive patterns

Strategy: try-catch

Validate before calling

// Optionally pre-validate with the same Fluid parser used internally before construction.

Try / catch

try { var t = new LiquidPromptTemplate(config); }
catch (ArgumentException ex) {
    // ex.Message contains the parser error detail; report line/token to the author
    logger.LogError(ex, "Liquid template parse failed"); throw;
}

Prevention

When it happens

Trigger: A Liquid template containing unbalanced tags (`{% if %}` with no `{% endif %}`), invalid filter syntax, unclosed output tags, or any syntax the Fluid-based parser rejects.

Common situations: Iterating on prompt text and introducing a typo; loading templates from files/DB where a partial edit corrupted the markup; using Liquid features unsupported by the configured parser.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/1360b5aef7444175. Report an issue: GitHub.