juanfont/headscale · error

%w: group %q expected string but got %T

Error message

%w: group %q expected string but got %T

What it means

While unmarshalling Groups, a member of a group array is not a JSON string (ErrInvalidGroupMember). The message names the group key and the Go type of the bad element.

Source

Thrown at hscontrol/policy/v2/types.go:1346

		if err != nil {
			return err
		}
	}

	// Then validate each field can be converted to []string
	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)
	}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Quote every group member so it is a JSON string
  2. If generating policy, ensure member values are serialized as strings

Example fix

// before
{"group:eng": [42]}
// after
{"group:eng": ["42@example.com"]}
Defensive patterns

Strategy: type-guard

Type guard

func allMembersStrings(v []any) bool {
	for _, m := range v { if _, ok := m.(string); !ok { return false } }
	return true
}

Prevention

When it happens

Trigger: A groups value containing a number, object, boolean, or null element, e.g. {"group:x": [42]} or {"group:x": [null]}.

Common situations: Hand-editing JSON (not HuJSON) policy and forgetting quotes, or a template/generator emitting unquoted values.

Related errors


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/e38ea7e2348411dd. Report an issue: GitHub.