{"record":{"id":"60793ad48764ae02","repo":"juanfont/headscale","slug":"w-got-q-must-be-one-of-v","errorCode":null,"errorMessage":"%w: got %q, must be one of %v","messagePattern":"%w: got %q, must be one of (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hscontrol/policy/v2/types.go","lineNumber":748,"sourceCode":"\tAutoGroupSelf      AutoGroup = \"autogroup:self\"\n\tAutoGroupDangerAll AutoGroup = \"autogroup:danger-all\"\n)\n\nvar autogroups = []AutoGroup{\n\tAutoGroupInternet,\n\tAutoGroupMember,\n\tAutoGroupNonRoot,\n\tAutoGroupTagged,\n\tAutoGroupSelf,\n\tAutoGroupDangerAll,\n}\n\nfunc (ag *AutoGroup) Validate() error {\n\tif slices.Contains(autogroups, *ag) {\n\t\treturn nil\n\t}\n\n\treturn fmt.Errorf(\"%w: got %q, must be one of %v\", ErrInvalidAutogroup, *ag, autogroups)\n}\n\nfunc (ag *AutoGroup) UnmarshalJSON(b []byte) error {\n\t*ag = AutoGroup(strings.Trim(string(b), `\"`))\n\n\terr := ag.Validate()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (ag *AutoGroup) String() string {\n\treturn string(*ag)\n}\n\n// MarshalJSON marshals the AutoGroup to JSON.","sourceCodeStart":730,"sourceCodeEnd":766,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/hscontrol/policy/v2/types.go#L730-L766","documentation":"AutoGroup.Validate rejected the token because it is not one of the known autogroups (autogroup:member, autogroup:tagged, autogroup:self, autogroup:internet, autogroup:nonroot, autogroup:danger-all). The error lists the accepted set; validation happens at policy unmarshal time.","triggerScenarios":"Values like 'autogroup:members' (plural), 'autogroup:admin', or 'autogroup:self ' (trailing space). slices.Contains(autogroups, ag) is false in AutoGroup.Validate.","commonSituations":"Typos and pluralization from memory; copying autogroup names from other systems' docs; headscale version differences where newer autogroups are unknown to older validators.","solutions":["Use an autogroup exactly as listed in the error message, e.g. 'autogroup:member'.","Check for trailing whitespace or quotes in the HuJSON value.","If you need 'autogroup:danger-all' or similar, upgrade headscale to a version that includes it.","If no autogroup fits, express the intent with groups/tags/CIDRs."],"exampleFix":"// before\n\"src\": [\"autogroup:members\"]\n\n// after\n\"src\": [\"autogroup:member\"]","handlingStrategy":"validation","validationCode":"var knownAutogroups = []string{\"autogroup:member\", \"autogroup:tagged\", \"autogroup:self\", \"autogroup:internet\", \"autogroup:nonroot\", \"autogroup:danger-all\"}\nfunc validAutogroup(s string) bool { return slices.Contains(knownAutogroups, s) }","typeGuard":null,"tryCatchPattern":"if err := ag.Validate(); err != nil {\n    if errors.Is(err, v2.ErrInvalidAutogroup) {\n        // error message lists all valid names; pick one exactly\n    }\n    return err\n}","preventionTips":["Copy autogroup names from the error message itself — it enumerates valid values.","Pin policy docs to the deployed headscale version.","Add a CI vocabulary check for autogroup tokens."],"tags":["policy","acl","validation","autogroups","configuration","go"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}