temporalio/temporal · error

where expression is nil

Error message

where expression is nil

What it means

Thrown by gcloud queryParser.convertWhereExpr when the SQL WHERE expression handed to it is nil. Parse extracts stmt.(*sqlparser.Select).Where.Expr and passes it here; a nil expression means the query had no WHERE clause at all. The GCloud archival visibility query parser only supports filtering queries, so a query without a WHERE clause is rejected.

Source

Thrown at common/archiver/gcloud/query_parser.go:80

	parsedQuery := &parsedQuery{}
	if err := p.convertWhereExpr(whereExpr, parsedQuery); err != nil {
		return nil, err
	}

	if (parsedQuery.closeTime.IsZero() && parsedQuery.startTime.IsZero()) || (!parsedQuery.closeTime.IsZero() && !parsedQuery.startTime.IsZero()) {
		return nil, errors.New("requires a StartTime or CloseTime")
	}

	if parsedQuery.searchPrecision == nil {
		return nil, errors.New("SearchPrecision is required when searching for 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

  1. Provide a non-empty WHERE clause, e.g. `WHERE CloseTime = '2024-01-01T00:00:00Z' AND SearchPrecision = 'Day'`.
  2. Validate/trim the query string before calling Parse and reject empty input with a clearer error upstream.
  3. If the intent is to list all workflows, use the appropriate list API instead of the archival visibility query parser.

Example fix

// before
query := r.URL.Query().Get("query") // may be ""
parsed, err := parser.Parse(query)

// after
query := r.URL.Query().Get("query")
if strings.TrimSpace(query) == "" {
    return nil, errors.New("query must contain a WHERE clause")
}
parsed, err := parser.Parse(query)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(query) == "" {
	return nil, errors.New("visibility query must contain a WHERE clause")
}
parsed, err := parser.Parse(query)

Prevention

When it happens

Trigger: Calling Parse with a query string that renders an empty WHERE clause, e.g. Parse("") or Parse(" ") — the sqlquery.QueryTemplate wraps the input in a SELECT whose WHERE expr is nil when no condition is given. Also triggered if convertParenExpr/convertAndExpr recurse into a nil sub-expression.

Common situations: A user runs `temporal workflow list` with an empty or whitespace-only --query against GCloud archival visibility; or code builds a query dynamically and drops the WHERE condition; or a parenthesized expression evaluates to nil after parsing.

Related errors


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