temporalio/temporal · error

can not query %s multiple times

Error message

can not query %s multiple times

What it means

The parser disallows repeating the same filter column in one archive query; workflowType can only be set once. A second comparison on WorkflowType (or WorkflowTypeName mapping to the same field) triggers this error, since ANDing two distinct type values can never match.

Source

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

	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)
		}
		if parsedQuery.workflowType != nil {
			return fmt.Errorf("can not query %s multiple times", colNameStr)
		}
		parsedQuery.workflowType = new(val)
	case WorkflowID:
		val, err := sqlquery.ExtractStringValue(valStr)
		if err != nil {
			return err
		}
		if op != "=" {
			return fmt.Errorf("only operation = is support for %s", WorkflowID)
		}
		if parsedQuery.workflowID != nil {
			return fmt.Errorf("can not query %s multiple times", WorkflowID)
		}
		parsedQuery.workflowID = new(val)
	case CloseTime:
		timestamp, err := sqlquery.ConvertToTime(valStr)
		if err != nil {
			return err

View on GitHub (pinned to bde624efd1)

Solutions

  1. Keep exactly one WorkflowType (or WorkflowTypeName) clause per query
  2. If you need multiple types, run one archive query per type and merge results client-side
  3. Check whether legacy WorkflowTypeName and WorkflowType are both present in the generated query and remove the duplicate

Example fix

// before
`WorkflowType = "A" AND WorkflowType = "B"`
// after
`WorkflowType = "B"` // or run one query per type and merge results
Defensive patterns

Strategy: validation

Validate before calling

n := strings.Count(q, "WorkflowType") + strings.Count(q, "WorkflowTypeName")
if n > 1 {
    return fmt.Errorf("query must contain at most one WorkflowType filter")
}

Try / catch

parsed, err := parser.Parse(q)
if err != nil {
    var perr *fmt.Errorf
    if errors.As(err, &perr) && strings.Contains(err.Error(), "multiple times") {
        // de-duplicate filters and retry once
    }
    return err
}

Prevention

When it happens

Trigger: Parsing e.g. `WorkflowType = 'A' AND WorkflowType = 'B'`, or mixing the legacy name with the new one: `WorkflowTypeName = 'A' AND WorkflowType = 'B'` — both write parsedQuery.workflowType, so the second is rejected.

Common situations: Users trying OR-like semantics via multiple type clauses; combining legacy and new filter names without realizing they share the same field; query builders appending the type filter twice.

Related errors


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