hashicorp/nomad · error
error parsing topics: %w
Error message
error parsing topics: %w
What it means
EventStream parses the query string's topic parameters into a map of structs.Topic to key lists via parseEventTopics. Any failure from parseTopic for an individual topic= query parameter is wrapped with this message and returned to the stream request.
Source
Thrown at command/agent/event_endpoint.go:221
codedErr := errs.Wait()
if codedErr != nil && strings.Contains(codedErr.Error(), io.ErrClosedPipe.Error()) {
codedErr = nil
}
return nil, codedErr
}
func parseEventTopics(query url.Values) (map[structs.Topic][]string, error) {
raw, ok := query["topic"]
if !ok {
return allTopics(), nil
}
topics := make(map[structs.Topic][]string)
for _, topic := range raw {
k, v, err := parseTopic(topic)
if err != nil {
return nil, fmt.Errorf("error parsing topics: %w", err)
}
topics[structs.Topic(k)] = append(topics[structs.Topic(k)], v)
}
return topics, nil
}
func parseTopic(topic string) (string, string, error) {
parts := strings.Split(topic, ":")
// infer wildcard if only given a topic
if len(parts) == 1 {
return topic, "*", nil
} else if len(parts) != 2 {
return "", "", fmt.Errorf("Invalid key value pair for topic, topic: %s", topic)
}
return parts[0], parts[1], nil
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Use at most one colon per topic parameter: topic=NodeRegistration:node1 or topic=Deployment.
- Pass multiple topics as repeated parameters: topic=Evaluation:*&topic=Deployment:*.
- URL-encode any colon-bearing payload or split it into separate parameters.
- Use the wildcard topic=* to subscribe to everything and filter client-side.
Example fix
// before GET /v1/event/stream?topic=Deployment:abc:def // after GET /v1/event/stream?topic=Deployment:*
Defensive patterns
Strategy: validation
Validate before calling
function buildTopicParam(key, value = '*') {
if (/[\s]/.test(key) || (value && value.includes(':'))) {
throw new Error(`invalid topic ${key}:${value}`)
}
return `topic=${encodeURIComponent(key)}:${encodeURIComponent(value)}`
} Type guard
func validTopicParam(s string) bool {
return strings.Count(s, ":") <= 1
} Try / catch
topics, err := parseEventTopics(raw)
if err != nil {
http.Error(w, "bad topic parameter; use topic=Name:value with at most one colon", 400)
return
} Prevention
- Keep at most one colon per topic parameter.
- Use repeated topic= parameters for multiple subscriptions.
- URL-encode keys and values with encodeURI/encodeURIComponent.
- Prefer wildcard topic=* and filter client-side when unsure.
When it happens
Trigger: GET /v1/event/stream with a topic= query parameter that parseTopic rejects — e.g. a value containing more than one colon such as topic=Deployment:abc:def.
Common situations: URL-encoded values containing colons (UUIDs are fine, but timestamps or joined key:value payloads are not); concatenating multiple key=value pairs into a single topic parameter.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- Invalid key value pair for topic, topic: %s
- error parsing offset: %v
- error parsing limit: %v
- failed to parse follow field to boolean: %v
- Request body is empty
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/cd991b965d980fd8.
Report an issue: GitHub.