{"record":{"id":"7fb4fb065ba3b65b","repo":"temporalio/temporal","slug":"where-expression-is-nil-7fb4fb","errorCode":null,"errorMessage":"where expression is nil","messagePattern":"where expression is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/archiver/s3store/query_parser.go","lineNumber":86,"sourceCode":"\tif parsedQuery.workflowID != nil && parsedQuery.workflowType != nil {\n\t\treturn nil, errors.New(\"only one of WorkflowId or WorkflowType can be specified in a query\")\n\t}\n\tif parsedQuery.closeTime != nil && parsedQuery.startTime != nil {\n\t\treturn nil, errors.New(\"only one of StartTime or CloseTime can be specified in a query\")\n\t}\n\tif (parsedQuery.closeTime != nil || parsedQuery.startTime != nil) && parsedQuery.searchPrecision == nil {\n\t\treturn nil, errors.New(\"SearchPrecision is required when searching for a StartTime or CloseTime\")\n\t}\n\n\tif parsedQuery.closeTime == nil && parsedQuery.startTime == nil && parsedQuery.searchPrecision != nil {\n\t\treturn nil, errors.New(\"SearchPrecision requires a StartTime or CloseTime\")\n\t}\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":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/archiver/s3store/query_parser.go#L68-L104","documentation":"convertWhereExpr unwraps the WHERE expression of the parsed SELECT; a nil expression means the query had no WHERE clause at all. Since the archival query dialect requires at least a WorkflowId/WorkflowType filter, the parser rejects nil immediately with this error.","triggerScenarios":"Calling Parse with an empty query string (the sqlquery.QueryTemplate yields a SELECT without WHERE when the where-part is empty) or otherwise producing a statement whose Where is nil.","commonSituations":"Empty search input passed straight through from a UI; string concatenation that drops the WHERE clause when no filters are set; template misuse in sqlquery.QueryTemplate.","solutions":["Ensure a non-empty WHERE clause is passed to Parse, e.g. \"WorkflowId = '<id>'\".","Guard callers: return a clearer validation error to the user before invoking Parse when the query is blank.","Check how the query string is interpolated into sqlquery.QueryTemplate and fix empty-input handling upstream."],"exampleFix":"// before\nresult, err := parser.Parse(\"\")\n// after\nif query == \"\" {\n    return nil, errors.New(\"query must contain a WorkflowId or WorkflowType filter\")\n}\nresult, err := parser.Parse(query)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(query) == \"\" {\n    return errors.New(\"query must not be empty; filter by WorkflowId or WorkflowType\")\n}","typeGuard":null,"tryCatchPattern":"pq, err := parser.Parse(query)\nif err != nil {\n    if strings.Contains(err.Error(), \"where expression is nil\") {\n        return nil, status.Error(codes.InvalidArgument, \"archival query requires a WHERE clause\")\n    }\n    return nil, err\n}","preventionTips":["Never pass raw empty search input to Parse; check for blank strings first.","Provide a default minimal filter (e.g. WorkflowType) when users submit no criteria.","Verify the query template interpolation preserves the WHERE clause."],"tags":["go","archival","query-validation","s3store"],"backgroundTag":"empty-query-clause","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}