temporalio/temporal · error

SearchPrecision is required when searching for a StartTime o

Error message

SearchPrecision is required when searching for a StartTime or CloseTime

What it means

When a time filter (StartTime or CloseTime) is present, the archiver needs SearchPrecision (Day|Hour|Minute|Second) to compute the time window over which archived files are scanned. Parse returns this error if a time predicate exists but no SearchPrecision predicate was parsed.

Source

Thrown at common/archiver/s3store/query_parser.go:75

	if err != nil {
		return nil, err
	}
	whereExpr := stmt.(*sqlparser.Select).Where.Expr
	parsedQuery := &parsedQuery{}
	if err := p.convertWhereExpr(whereExpr, parsedQuery); err != nil {
		return nil, err
	}
	if parsedQuery.workflowID == nil && parsedQuery.workflowType == nil {
		return nil, errors.New("WorkflowId or WorkflowType is required in query")
	}
	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)

View on GitHub (pinned to bde624efd1)

Solutions

  1. Add "AND SearchPrecision = '<Day|Hour|Minute|Second>'" to the query, matching the time field used.
  2. Choose precision loosely (Day) to widen the scan window if unsure of exact times.
  3. Update query-building code to always emit SearchPrecision alongside any StartTime/CloseTime filter.

Example fix

// before
parser.Parse("WorkflowId = 'w1' AND CloseTime > '2024-01-01'")
// after
parser.Parse("WorkflowId = 'w1' AND CloseTime > '2024-01-01' AND SearchPrecision = 'Day'")
Defensive patterns

Strategy: validation

Validate before calling

validPrecisions := map[string]bool{"Day": true, "Hour": true, "Minute": true, "Second": true}
if (strings.Contains(query, "StartTime") || strings.Contains(query, "CloseTime")) &&
    !strings.Contains(query, "SearchPrecision") {
    return errors.New("SearchPrecision is required with a time filter")
}

Try / catch

pq, err := parser.Parse(query)
if err != nil {
    if strings.Contains(err.Error(), "SearchPrecision is required") {
        return nil, status.Error(codes.InvalidArgument, "add SearchPrecision (Day|Hour|Minute|Second) to your time-filtered archival query")
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling Parse with "WorkflowId = 'w1' AND StartTime > '2024-01-01T00:00:00Z'" and no "SearchPrecision = '...'" comparison in the WHERE clause.

Common situations: Users unaware the archival query dialect requires SearchPrecision; query builders that treat SearchPrecision as optional; migrating queries from SQL visibility which has no such requirement.

Related errors


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