{"record":{"id":"726bb262e284ba4d","repo":"AdguardTeam/AdGuardHome","slug":"invalid-tag-q","errorCode":null,"errorMessage":"invalid tag: %q","messagePattern":"invalid tag: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/persistent.go","lineNumber":161,"sourceCode":"\t\treturn errors.Error(\"uid required\")\n\t}\n\n\tconf, err := proxy.ParseUpstreamsConfig(c.Upstreams, &upstream.Options{\n\t\tLogger: l.With(aghslog.KeyUpstreamType, aghslog.UpstreamTypeTest),\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid upstream servers: %w\", err)\n\t}\n\n\terr = conf.Close()\n\tif err != nil {\n\t\tl.ErrorContext(ctx, \"client: closing upstream config\", slogutil.KeyError, err)\n\t}\n\n\tfor _, t := range c.Tags {\n\t\t_, ok := slices.BinarySearch(allTags, t)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid tag: %q\", t)\n\t\t}\n\t}\n\n\t// TODO(s.chzhen):  Move to the constructor.\n\tslices.Sort(c.Tags)\n\n\treturn nil\n}\n\n// SetIDs parses a list of strings into typed fields and returns an error if\n// there is one.\nfunc (c *Persistent) SetIDs(ids []string) (err error) {\n\tfor _, id := range ids {\n\t\terr = c.setID(id)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/client/persistent.go#L143-L179","documentation":"Validation error from persistent client validation: one of the client's tags is not present in the global sorted list of known tags (allTags). Tags must exist in the server's tag set before they can be attached to a client.","triggerScenarios":"Calling Storage.Add or Storage.Update with c.Tags containing a tag name that was never created via the tag configuration API (checked by binary search against allTags).","commonSituations":"Hardcoding tag names in config or scripts instead of creating them first, renaming/deleting a tag while clients still reference it, case mismatches between configured tag names and client tags.","solutions":["Create the missing tag via the tag settings API/UI first, then retry Add/Update","Check for typos and case differences between the client's tag and the configured tags","If a tag was renamed, update the client's Tags slice to the new name"],"exampleFix":"// before\nc.Tags = []string{\"device-tv\"} // tag \"device-tv\" not defined\n\n// after\n// 1. create tag \"device-tv\" in settings, then:\nc.Tags = []string{\"device-tv\"}","handlingStrategy":"validation","validationCode":"known := map[string]bool{}\nfor _, t := range allTags { known[t] = true }\nfor _, t := range c.Tags {\n    if !known[t] { /* reject or auto-create tag */ }\n}","typeGuard":null,"tryCatchPattern":"if err := s.Add(ctx, c); err != nil && strings.Contains(err.Error(), \"invalid tag\") { /* create tag, then retry */ }","preventionTips":["Create tags via the settings API before assigning them to clients","Use dropdowns of existing tags in UIs instead of free-text input"],"tags":["client","tags","validation"],"backgroundTag":"unknown-tag-reference","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}