temporalio/temporal · error

unknown workflow close status: %s

Error message

unknown workflow close status: %s

What it means

convertStatusStr in the filestore visibility query parser translates a query's status literal (e.g. CloseTime='completed' or a numeric enum string) into an enumspb.WorkflowExecutionStatus. If the string matches none of the known names or numeric codes, it returns 'unknown workflow close status: %s'. The parser is case-insensitive and trims whitespace before matching.

Source

Thrown at common/archiver/filestore/query_parser.go:222

}

func convertStatusStr(statusStr string) (enumspb.WorkflowExecutionStatus, error) {
	statusStr = strings.ToLower(strings.TrimSpace(statusStr))
	switch statusStr {
	case "completed", convert.Int32ToString(int32(enumspb.WORKFLOW_EXECUTION_STATUS_COMPLETED)):
		return enumspb.WORKFLOW_EXECUTION_STATUS_COMPLETED, nil
	case "failed", convert.Int32ToString(int32(enumspb.WORKFLOW_EXECUTION_STATUS_FAILED)):
		return enumspb.WORKFLOW_EXECUTION_STATUS_FAILED, nil
	case "canceled", convert.Int32ToString(int32(enumspb.WORKFLOW_EXECUTION_STATUS_CANCELED)):
		return enumspb.WORKFLOW_EXECUTION_STATUS_CANCELED, nil
	case "terminated", convert.Int32ToString(int32(enumspb.WORKFLOW_EXECUTION_STATUS_TERMINATED)):
		return enumspb.WORKFLOW_EXECUTION_STATUS_TERMINATED, nil
	case "continuedasnew", "continued_as_new", convert.Int32ToString(int32(enumspb.WORKFLOW_EXECUTION_STATUS_CONTINUED_AS_NEW)):
		return enumspb.WORKFLOW_EXECUTION_STATUS_CONTINUED_AS_NEW, nil
	case "timedout", "timed_out", convert.Int32ToString(int32(enumspb.WORKFLOW_EXECUTION_STATUS_TIMED_OUT)):
		return enumspb.WORKFLOW_EXECUTION_STATUS_TIMED_OUT, nil
	default:
		return 0, fmt.Errorf("unknown workflow close status: %s", statusStr)
	}
}

View on GitHub (pinned to bde624efd1)

Solutions

  1. Use a supported close status literal: completed, failed, canceled, terminated, continued_as_new, or timed_out (case-insensitive)
  2. Use the numeric enum value as a string (e.g. CloseStatus='1' for completed)
  3. Remove the status filter if querying workflows that are not yet closed — the file archiver only stores closed executions

Example fix

// before
`CloseTime > 0 and CloseStatus = "running"`
// after
`CloseTime > 0 and CloseStatus = "completed"`
Defensive patterns

Strategy: validation

Validate before calling

allowed := map[string]bool{"completed":true,"failed":true,"canceled":true,"terminated":true,"continued_as_new":true,"timed_out":true}
if !allowed[strings.ToLower(status)] { return fmt.Errorf("unsupported close status %q for file archiver query", status) }

Type guard

func isKnownCloseStatus(s string) bool {
  switch strings.ToLower(strings.TrimSpace(s)) {
  case "completed", "failed", "canceled", "terminated", "continuedasnew", "continued_as_new", "timedout", "timed_out":
    return true
  }
  return false
}

Try / catch

resp, err := client.ArchiveQuery(ctx, req)
if err != nil {
  if strings.Contains(err.Error(), "unknown workflow close status") {
    return nil, fmt.Errorf("bad status filter in query %q: %w", req.Query, err)
  }
  return nil, err
}

Prevention

When it happens

Trigger: Running a visibility query against the file archiver with a CloseStatus/Status comparison value that is not one of completed, failed, canceled, terminated, continued_as_new (also continuedasnew), timed_out (also timedout), or their numeric enum equivalents (e.g. status='running' or a misspelled value).

Common situations: Users querying open workflows by close status (open is not a close status), typos like 'compleated', or using status names not supported by the file-based archiver.

Related errors


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