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

  1. Use a bare column name on the left side: `WHERE WorkflowType = "X"`
  2. Remove function calls, casts, or arithmetic from filter keys
  3. Inspect the expression echoed in the error to find the offending syntax
  4. 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

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


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/dbe9b6ba2d569e91. Report an issue: GitHub.