juanfont/headscale · error
%w: group %q got string: %q
Error message
%w: group %q got string: %q
What it means
A groups entry's value is a bare JSON string instead of an array of strings (ErrGroupValueNotArray). The message shows the offending string.
Source
Thrown at hscontrol/policy/v2/types.go:1352
rawGroups := make(map[string][]string)
for key, value := range rawMap {
switch v := value.(type) {
case []any:
// Convert []interface{} to []string
var stringSlice []string
for _, item := range v {
if str, ok := item.(string); ok {
stringSlice = append(stringSlice, str)
} else {
return fmt.Errorf("%w: group %q expected string but got %T", ErrInvalidGroupMember, key, item)
}
}
rawGroups[key] = stringSlice
case string:
return fmt.Errorf("%w: group %q got string: %q", ErrGroupValueNotArray, key, v)
default:
return fmt.Errorf("%w: group %q got %T", ErrGroupValueNotArray, key, v)
}
}
// Reject group-in-group references. Reverse-sort the keys so the
// reported (parent, child) pair names the deepest non-leaf parent
// first.
keys := make([]string, 0, len(rawGroups))
for k := range rawGroups {
keys = append(keys, k)
}
slices.Sort(keys)
slices.Reverse(keys)
for _, key := range keys {
for _, u := range rawGroups[key] {View on GitHub (pinned to 565fd254d0)
Solutions
- Wrap the value in square brackets to make it an array
- Run headscale policy check (or equivalent validation) before applying
Example fix
// before
{"group:eng": "dev@example.com"}
// after
{"group:eng": ["dev@example.com"]} Defensive patterns
Strategy: validation
Validate before calling
func groupValueIsArray(raw map[string]any) bool {
for _, v := range raw { if _, ok := v.([]any); !ok { return false } }
return true
} Prevention
- Always bracket group values, even single-member groups
When it happens
Trigger: Writing "group:x": "user@example.com" instead of ["user@example.com"] in the groups map.
Common situations: Single-member groups written without brackets; converting YAML-ish config to HuJSON/JSON and dropping the list syntax.
Related errors
- invalid group member type
- group value must be an array of users
- %w: group %q expected string but got %T
- %w: group %q got %T
- group must start with 'group:'
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/fe9bede26574a358.
Report an issue: GitHub.