temporalio/temporal · error
invalid filter name: %s
Error message
invalid filter name: %s
What it means
In the S3 archive query parser, the left-hand side of each WHERE comparison must be a plain column name (sqlparser.ColName). If the left side is any other SQL expression — a function call, literal, arithmetic, or keyword — convertComparisonExpr returns this error with the printed expression. This catches structurally invalid filters early, before column-name validation.
Source
Thrown at common/archiver/s3store/query_parser.go:115
return errors.New("only comparison and \"and\" expression is supported")
}
}
func (p *queryParser) convertParenExpr(parenExpr *sqlparser.ParenExpr, parsedQuery *parsedQuery) error {
return p.convertWhereExpr(parenExpr.Expr, parsedQuery)
}
func (p *queryParser) convertAndExpr(andExpr *sqlparser.AndExpr, parsedQuery *parsedQuery) error {
if err := p.convertWhereExpr(andExpr.Left, parsedQuery); err != nil {
return err
}
return p.convertWhereExpr(andExpr.Right, parsedQuery)
}
func (p *queryParser) convertComparisonExpr(compExpr *sqlparser.ComparisonExpr, parsedQuery *parsedQuery) error {
colName, ok := compExpr.Left.(*sqlparser.ColName)
if !ok {
return fmt.Errorf("invalid filter name: %s", sqlparser.String(compExpr.Left))
}
colNameStr := sqlparser.String(colName)
op := compExpr.Operator
valExpr, ok := compExpr.Right.(*sqlparser.SQLVal)
if !ok {
return fmt.Errorf("invalid value: %s", sqlparser.String(compExpr.Right))
}
valStr := sqlparser.String(valExpr)
switch colNameStr {
case WorkflowTypeName, WorkflowType:
val, err := sqlquery.ExtractStringValue(valStr)
if err != nil {
return err
}
if op != "=" {
return fmt.Errorf("only operation = is support for %s", colNameStr)
}View on GitHub (pinned to bde624efd1)
Solutions
- Use a bare column name on the left side: `WHERE WorkflowType = "X"`
- Remove function calls, casts, or arithmetic from filter keys
- Inspect the expression echoed in the error to find the offending syntax
- Validate the query only uses supported columns (WorkflowType/WorkflowTypeName, WorkflowID, CloseTime, StartTime, etc.)
Example fix
// before query := `WHERE UPPER(WorkflowType) = "MyType"` // after query := `WHERE WorkflowType = "MyType"`
Defensive patterns
Strategy: validation
Validate before calling
for _, clause := range clauses {
lhs := strings.Fields(clause)[0]
if strings.ContainsAny(lhs, "(+\"") {
return fmt.Errorf("filter key must be a bare column, got %q", lhs)
}
} Try / catch
q, err := parseArchiveQuery(raw)
if err != nil {
return fmt.Errorf("LHS of filter must be a column: %w", err)
} Prevention
- Never wrap filter keys in functions or casts
- Generate queries from typed builders rather than string concatenation
- Keep both sides of comparisons as column = literal
When it happens
Trigger: A WHERE clause like `WHERE UPPER(WorkflowType) = "X"`, `WHERE "literal" = "v"`, or `WHERE WorkflowID + "" = "w"` parsed by the s3store archiver's query parser.
Common situations: Hand-written SQL-style queries using functions or expressions; query builders that wrap column names in functions or quotes; copy-pasted SQL from other systems with computed predicates.
Related errors
- invalid value: %s
- only one expression is allowed for %s
- invalid value for %s: %s
- unknown filter name: %s
- only comparison and "and" expression is supported
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/dbe9b6ba2d569e91.
Report an issue: GitHub.