{"record":{"id":"bbc3ecb0319ce08a","repo":"temporalio/temporal","slug":"where-expression-is-nil","errorCode":null,"errorMessage":"where expression is nil","messagePattern":"where expression is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/archiver/gcloud/query_parser.go","lineNumber":80,"sourceCode":"\tparsedQuery := &parsedQuery{}\n\tif err := p.convertWhereExpr(whereExpr, parsedQuery); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif (parsedQuery.closeTime.IsZero() && parsedQuery.startTime.IsZero()) || (!parsedQuery.closeTime.IsZero() && !parsedQuery.startTime.IsZero()) {\n\t\treturn nil, errors.New(\"requires a StartTime or CloseTime\")\n\t}\n\n\tif parsedQuery.searchPrecision == nil {\n\t\treturn nil, errors.New(\"SearchPrecision is required when searching for a StartTime or CloseTime\")\n\t}\n\n\treturn parsedQuery, nil\n}\n\nfunc (p *queryParser) convertWhereExpr(expr sqlparser.Expr, parsedQuery *parsedQuery) error {\n\tif expr == nil {\n\t\treturn errors.New(\"where expression is nil\")\n\t}\n\n\tswitch expr := expr.(type) {\n\tcase *sqlparser.ComparisonExpr:\n\t\treturn p.convertComparisonExpr(expr, parsedQuery)\n\tcase *sqlparser.AndExpr:\n\t\treturn p.convertAndExpr(expr, parsedQuery)\n\tcase *sqlparser.ParenExpr:\n\t\treturn p.convertParenExpr(expr, parsedQuery)\n\tdefault:\n\t\treturn errors.New(\"only comparison and \\\"and\\\" expression is supported\")\n\t}\n}\n\nfunc (p *queryParser) convertParenExpr(parenExpr *sqlparser.ParenExpr, parsedQuery *parsedQuery) error {\n\treturn p.convertWhereExpr(parenExpr.Expr, parsedQuery)\n}\n","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/archiver/gcloud/query_parser.go#L62-L98","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Provide a non-empty WHERE clause, e.g. `WHERE CloseTime = '2024-01-01T00:00:00Z' AND SearchPrecision = 'Day'`.","Validate/trim the query string before calling Parse and reject empty input with a clearer error upstream.","If the intent is to list all workflows, use the appropriate list API instead of the archival visibility query parser."],"exampleFix":"// before\nquery := r.URL.Query().Get(\"query\") // may be \"\"\nparsed, err := parser.Parse(query)\n\n// after\nquery := r.URL.Query().Get(\"query\")\nif strings.TrimSpace(query) == \"\" {\n    return nil, errors.New(\"query must contain a WHERE clause\")\n}\nparsed, err := parser.Parse(query)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(query) == \"\" {\n\treturn nil, errors.New(\"visibility query must contain a WHERE clause\")\n}\nparsed, err := parser.Parse(query)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reject empty or whitespace-only queries at the CLI/UI layer before they reach the archiver.","When building queries dynamically, assert the WHERE fragment is non-empty before composing.","Use list-all-workflow APIs instead of the archival query parser for unfiltered listing."],"tags":["archival","gcloud","query-parsing","visibility"],"backgroundTag":"empty-query-expression","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}