OrchardCMS/OrchardCore · error · ValidationException
The variable ' ' was used in the recipe but not defined…
Error message
The variable '{0}' was used in the recipe but not defined. Make sure you add the '{0}' variable in the '{1}' section of the recipe. What it means
VariablesMethodProvider.GetVariableValueAsync resolves a recipe variable referenced by the [[VariableName]] syntax. If the named variable does not exist in the recipe's 'variables' section, it throws a ValidationException telling the author to define the variable. This fails fast during recipe execution rather than silently injecting null.
Solutions
- Add the missing variable to the recipe's "variables" section: "variables": { "MyVar": "value" }.
- Fix the reference typo in the step so it matches a declared variable name exactly (case included).
- If the value should come from user input at setup, declare it in the recipe parameters/setup settings instead of referencing an undeclared name.
- Search the recipe file for all [[...]] references and reconcile them against declared variables.
Example fix
// before (step references [[SiteName]] but variables section lacks it)
{
"variables": { },
"steps": [
{ "type": "settings", "values": { "SiteName": "[[SiteName]]" } }
]
}
// after
{
"variables": { "SiteName": "My Site" },
"steps": [
{ "type": "settings", "values": { "SiteName": "[[SiteName]]" } }
]
} Defensive patterns
Strategy: validation
Validate before calling
var json = JsonNode.Parse(File.ReadAllText(recipePath));
var variables = json?["variables"]?.AsObject();
foreach (var reference in System.Text.RegularExpressions.Regex.Matches(
json!.ToJsonString(), "\[\[(\w+)\]\]"))
{
var name = reference.Groups[1].Value;
if (variables?[name] == null)
throw new Exception($"Recipe references undefined variable '{name}'");
} Try / catch
try
{
await recipeExecutor.ExecuteAsync(executionId, descriptor, environment, logger);
}
catch (ValidationException ex)
{
logger.LogError(ex, "Recipe references an undefined variable: {Message}", ex.Message);
} Prevention
- Declare every variable referenced with [[Name]] in the recipe's "variables" section.
- Match variable names exactly (case-sensitive) between declarations and references.
- When copying steps between recipes, copy their variable declarations too.
- Grep the recipe for [[...]] patterns and reconcile against the variables section before deploying.
When it happens
Trigger: A recipe step references a variable (e.g., [[MyVar]] in a script or parameter) that is not declared in the recipe's "variables" section, so VariablesMethodProvider looks it up in the variables dictionary and finds null.
Common situations: Typo in a [[VariableName]] reference vs. its declaration; a variable deleted from the 'variables' section while steps still reference it; copying steps from another recipe without copying the variables; case-sensitivity mismatch between reference and declaration.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- The file extension should start with a dot.
- Top-level JSON element must be an object. Instead
- The ClamAV antivirus scanner is enabled but the port…
- The ClamAV antivirus scanner is enabled but the connection…
- The ClamAV antivirus scanner is enabled but the transfer…
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/60b4816f14e26b71.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Recipes.Core/VariablesMethodProvider.cs:46
public IEnumerable<GlobalMethod> GetMethods()
{
yield return _globalMethod;
}
private static async Task<object> GetVariableValueAsync(
IServiceProvider serviceProvider,
JsonObject variables,
List<IGlobalMethodProvider> scopedMethodProviders,
string name)
{
var variable = variables[name];
if (variable == null)
{
var S = serviceProvider.GetService<IStringLocalizer<VariablesMethodProvider>>();
throw new ValidationException(S["The variable '{0}' was used in the recipe but not defined. Make sure you add the '{0}' variable in the '{1}' section of the recipe.", name, GlobalMethodName]);
}
var value = variable.Value<string>();
// Replace variable value while the result returns another script.
while (value.StartsWith('[') && value.EndsWith(']'))
{
value = value.Trim('[', ']');
value = (await ScriptingManager.EvaluateAsync(value, null, null, scopedMethodProviders) ?? "").ToString();
variables[name] = value;
}
return value;
}
}
View on GitHub (pinned to 4306c0717f)