ssssssss-team/spider-flow · error · TemplateException
{message}
Error message
{message} What it means
ExpressionError.error builds a caret-highlighted message pointing at the failing span within the expression line and throws freemarker.template.TemplateException with that message and location. The '{message}' placeholder in the error record simply stands for the generated, location-annotated message text.
Solutions
- Read the caret position in the message to find the exact character range that failed, then correct the expression syntax there.
- Verify all variables referenced in the expression exist in the execution context at that node.
- Test the expression in isolation (evaluate just the expression against sample context) before re-running the flow.
Example fix
// before (expression)
${a.b.c} // a is null
// after
${(a.b.c)!'default'} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate expression before execution: try compiling it against a sample context
try { expressionService.compile(expr); } catch (Exception e) { /* surface syntax error to user before run */ } Try / catch
try {
Object v = expressionEngine.execute(expr, context);
} catch (TemplateException e) {
// message contains caret-marked location of the failing span in the expression line
log.error("Expression failed: {}", e.getMessage());
} Prevention
- Use the caret position in the error message to pinpoint and fix the failing expression range.
- Reference variables with null-safe defaults, e.g. ${(a.b)!'default'}.
- Test expressions in the flow designer's expression evaluator before saving the flow.
When it happens
Trigger: Any failed expression evaluation routed through ExpressionError.error: invalid FreeMarker/Aviator expression syntax in a spider flow field, unknown variables in the expression, or a wrapped cause exception.
Common situations: Users type malformed expressions in the flow designer (unbalanced parentheses, wrong function name, referencing a variable that doesn't exist in context), or an expression worked in an older engine version but the syntax/variable changed.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- file is null
- Couldn't get value of field '" + javaField.getName() + "'…
- Couldn't call method '" + javaMethod.getName() + "' with…
AI-assisted analysis of ssssssss-team/spider-flow@c799cca99c (2026-09-08).
Data as JSON: /api/errors/cd26569f9aab8946.
Report an issue: GitHub.
Appendix: source
Thrown at spider-flow-core/src/main/java/org/spiderflow/core/expression/ExpressionError.java:51
/** Create an error message based on the provided message and location, highlighting the location in the line on which the
* error happened. Throws a {@link TemplateException} **/
public static void error (String message, Span location, Throwable cause) {
Line line = location.getLine();
message = "Error (" + line.getLineNumber() + "): " + message + "\n\n";
message += line.getText();
message += "\n";
int errorStart = location.getStart() - line.getStart();
int errorEnd = errorStart + location.getText().length() - 1;
for (int i = 0, n = line.getText().length(); i < n; i++) {
boolean useTab = line.getText().charAt(i) == '\t';
message += i >= errorStart && i <= errorEnd ? "^" : useTab ? "\t" : " ";
}
if (cause == null)
throw new TemplateException(message, location);
else
throw new TemplateException(message, location, cause);
}
/** Create an error message based on the provided message and location, highlighting the location in the line on which the
* error happened. Throws a {@link TemplateException} **/
public static void error (String message, Span location) {
error(message, location, null);
}
/** Exception thrown by all basis-template code via {@link ExpressionError#error(String, Span)}. In case an error happens deep inside a
* list of included templates, the {@link #getMessage()} method will return a condensed error message. **/
public static class TemplateException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final Span location;
private final String errorMessage;
private TemplateException (String message, Span location) {View on GitHub (pinned to c799cca99c)