temporalio/temporal · error
where expression is nil
Error message
where expression is nil
What it means
convertWhereExpr unwraps the WHERE expression of the parsed SELECT; a nil expression means the query had no WHERE clause at all. Since the archival query dialect requires at least a WorkflowId/WorkflowType filter, the parser rejects nil immediately with this error.
Source
Thrown at common/archiver/s3store/query_parser.go:86
if parsedQuery.workflowID != nil && parsedQuery.workflowType != nil {
return nil, errors.New("only one of WorkflowId or WorkflowType can be specified in a query")
}
if parsedQuery.closeTime != nil && parsedQuery.startTime != nil {
return nil, errors.New("only one of StartTime or CloseTime can be specified in a query")
}
if (parsedQuery.closeTime != nil || parsedQuery.startTime != nil) && parsedQuery.searchPrecision == nil {
return nil, errors.New("SearchPrecision is required when searching for a StartTime or CloseTime")
}
if parsedQuery.closeTime == nil && parsedQuery.startTime == nil && parsedQuery.searchPrecision != nil {
return nil, errors.New("SearchPrecision requires a StartTime or CloseTime")
}
return parsedQuery, nil
}
func (p *queryParser) convertWhereExpr(expr sqlparser.Expr, parsedQuery *parsedQuery) error {
if expr == nil {
return errors.New("where expression is nil")
}
switch expr := expr.(type) {
case *sqlparser.ComparisonExpr:
return p.convertComparisonExpr(expr, parsedQuery)
case *sqlparser.AndExpr:
return p.convertAndExpr(expr, parsedQuery)
case *sqlparser.ParenExpr:
return p.convertParenExpr(expr, parsedQuery)
default:
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)
}
View on GitHub (pinned to bde624efd1)
Solutions
- Ensure a non-empty WHERE clause is passed to Parse, e.g. "WorkflowId = '<id>'".
- Guard callers: return a clearer validation error to the user before invoking Parse when the query is blank.
- Check how the query string is interpolated into sqlquery.QueryTemplate and fix empty-input handling upstream.
Example fix
// before
result, err := parser.Parse("")
// after
if query == "" {
return nil, errors.New("query must contain a WorkflowId or WorkflowType filter")
}
result, err := parser.Parse(query) Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(query) == "" {
return errors.New("query must not be empty; filter by WorkflowId or WorkflowType")
} Try / catch
pq, err := parser.Parse(query)
if err != nil {
if strings.Contains(err.Error(), "where expression is nil") {
return nil, status.Error(codes.InvalidArgument, "archival query requires a WHERE clause")
}
return nil, err
} Prevention
- Never pass raw empty search input to Parse; check for blank strings first.
- Provide a default minimal filter (e.g. WorkflowType) when users submit no criteria.
- Verify the query template interpolation preserves the WHERE clause.
When it happens
Trigger: Calling Parse with an empty query string (the sqlquery.QueryTemplate yields a SELECT without WHERE when the where-part is empty) or otherwise producing a statement whose Where is nil.
Common situations: Empty search input passed straight through from a UI; string concatenation that drops the WHERE clause when no filters are set; template misuse in sqlquery.QueryTemplate.
Related errors
- WorkflowId or WorkflowType is required in query
- only one of WorkflowId or WorkflowType can be specified in a
- only one of StartTime or CloseTime can be specified in a que
- SearchPrecision is required when searching for a StartTime o
- SearchPrecision requires a StartTime or CloseTime
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/7fb4fb065ba3b65b.
Report an issue: GitHub.