{"record":{"id":"88fc65c12f964aa5","repo":"temporalio/temporal","slug":"workflowid-or-workflowtype-is-required-in-query","errorCode":null,"errorMessage":"WorkflowId or WorkflowType is required in query","messagePattern":"WorkflowId or WorkflowType is required in query","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/archiver/s3store/query_parser.go","lineNumber":66,"sourceCode":")\n\n// NewQueryParser creates a new query parser for filestore\nfunc NewQueryParser() QueryParser {\n\treturn &queryParser{}\n}\n\nfunc (p *queryParser) Parse(query string) (*parsedQuery, error) {\n\tstmt, err := sqlparser.Parse(fmt.Sprintf(sqlquery.QueryTemplate, query))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\twhereExpr := stmt.(*sqlparser.Select).Where.Expr\n\tparsedQuery := &parsedQuery{}\n\tif err := p.convertWhereExpr(whereExpr, parsedQuery); err != nil {\n\t\treturn nil, err\n\t}\n\tif parsedQuery.workflowID == nil && parsedQuery.workflowType == nil {\n\t\treturn nil, errors.New(\"WorkflowId or WorkflowType is required in query\")\n\t}\n\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 {","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/archiver/s3store/query_parser.go#L48-L84","documentation":"The S3/filestore visibility archiver's queryParser.Parse validates every WHERE clause before scanning archived visibility records. It requires at least one of WorkflowId or WorkflowType as a filter, because without one the archiver would have to scan the entire archive. Parse returns this error when the parsed query contains neither filter.","triggerScenarios":"Calling s3store.NewQueryParser().Parse with a WHERE clause that only has time conditions (e.g. \"StartTime > '2024-01-01'\"), no WorkflowId/WorkflowType comparison, or an empty/invalid WHERE expression that sets neither parsedQuery.workflowID nor parsedQuery.workflowType.","commonSituations":"Users issuing archive-search queries similar to standard SQL visibility (where time-only filters are allowed); queries accidentally built with only SearchPrecision or time predicates; programmatic query builders that drop the workflow filter when the field is empty.","solutions":["Add \"WorkflowId = '<id>'\" to the WHERE clause.","Alternatively filter by \"WorkflowType = '<type>'\" (or the deprecated WorkflowTypeName alias).","If building queries programmatically, validate the where string contains a WorkflowId or WorkflowType predicate before calling Parse."],"exampleFix":"// before\nparser.Parse(\"StartTime > '2024-01-01T00:00:00Z' AND SearchPrecision = 'Day'\")\n// after\nparser.Parse(\"WorkflowId = 'my-workflow' AND StartTime > '2024-01-01T00:00:00Z' AND SearchPrecision = 'Day'\")","handlingStrategy":"validation","validationCode":"func hasRequiredFilter(query string) bool {\n    return strings.Contains(query, \"WorkflowId\") || strings.Contains(query, \"WorkflowType\")\n}","typeGuard":null,"tryCatchPattern":"pq, err := parser.Parse(query)\nif err != nil {\n    if strings.Contains(err.Error(), \"WorkflowId or WorkflowType is required\") {\n        return nil, status.Errorf(codes.InvalidArgument, \"archival query must filter by WorkflowId or WorkflowType\")\n    }\n    return nil, err\n}","preventionTips":["Always include a WorkflowId or WorkflowType equality predicate in archival visibility queries.","Sanitize user search input before building the WHERE clause.","Document the archival query dialect restrictions for query authors."],"tags":["go","archival","query-validation","s3store"],"backgroundTag":"query-filter-required","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}