temporalio/temporal · error
missing Legacy Query in PollWorkflowTaskQueueResponse
Error message
missing Legacy Query in PollWorkflowTaskQueueResponse
What it means
For legacy queries, the poll response must contain task.Query; respondQueryTaskCompleted rejects responses where Query is nil because there is no query to answer. This distinguishes a plain workflow task from a legacy query task.
Source
Thrown at common/testing/taskpoller/taskpoller.go:480
if err != nil {
return nil, err
}
return resp, nil
}
func (p *workflowTaskPoller) respondQueryTaskCompleted(
ctx context.Context,
task *workflowservice.PollWorkflowTaskQueueResponse,
reply *workflowservice.RespondQueryTaskCompletedRequest,
err error,
) (*workflowservice.RespondQueryTaskCompletedResponse, error) {
p.t.Helper()
if task == nil {
return nil, errors.New("missing PollWorkflowTaskQueueResponse")
}
if task.Query == nil {
return nil, errors.New("missing Legacy Query in PollWorkflowTaskQueueResponse")
}
if reply == nil {
return nil, errors.New("missing RespondQueryTaskCompletedRequest")
}
// setting the fields for RespondQueryTaskCompletedResponse
if reply.Namespace == "" {
reply.Namespace = p.namespace
}
if reply.TaskToken == nil {
reply.TaskToken = task.TaskToken
}
if err != nil {
reply.ErrorMessage = err.Error()
reply.Failure = &failurepb.Failure{
Message: err.Error(),
}View on GitHub (pinned to bde624efd1)
Solutions
- Route the polled task to HandleTask instead of HandleQuery when task.Query is nil
- Dispatch legacy queries through the legacy query path so the server includes Query in the poll response
- In mocks, populate resp.Query = &querypb.WorkflowQuery{...} before invoking handleQuery
Example fix
// before
poller.HandleQuery(ctx, task, reply) // task.Query is nil
// after
if task.Query == nil {
poller.HandleTask(ctx, task, reply)
} else {
poller.HandleQuery(ctx, task, reply)
} Defensive patterns
Strategy: type-guard
Validate before calling
if task != nil && task.Query == nil {
// route to HandleTask instead of HandleQuery
} Type guard
func isLegacyQueryTask(t *workflowservice.PollWorkflowTaskQueueResponse) bool {
return t != nil && t.Query != nil
} Try / catch
if !isLegacyQueryTask(task) {
return poller.HandleTask(ctx, task, reply)
}
return poller.HandleQuery(ctx, task, reply) Prevention
- Dispatch on task.Query before choosing the handler
- Ensure legacy queries are sent via the legacy query path
- Update mocks to populate Query for query tasks
When it happens
Trigger: handleQuery receives a PollWorkflowTaskQueueResponse whose Query field is nil — i.e. a normal workflow task was polled but routed to the query handler.
Common situations: Mixing up handleTask and handleQuery in test code; server/mock delivered a regular poll task instead of a legacy query task (query not sent via legacy path); SDK/version mismatch where queries no longer ride workflow-task polls.
Related errors
- missing PollWorkflowTaskQueueResponse
- missing RespondQueryTaskCompletedRequest
- missing RespondWorkflowTaskCompletedRequest return
- history is nil
- missing RespondActivityTaskCompletedRequest return
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/e6fb34c672c2ba78.
Report an issue: GitHub.