{"record":{"id":"0385904f539a668f","repo":"AdguardTeam/AdGuardHome","slug":"invalid-theme-q-supported-q-q-q","errorCode":null,"errorMessage":"invalid theme %q, supported: %q, %q, %q","messagePattern":"invalid theme %q, supported: %q, %q, %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/home/profilehttp.go","lineNumber":33,"sourceCode":"//\n// Keep in sync with client/src/helpers/constants.ts.\nconst (\n\tThemeAuto  Theme = \"auto\"\n\tThemeLight Theme = \"light\"\n\tThemeDark  Theme = \"dark\"\n)\n\n// UnmarshalText implements [encoding.TextUnmarshaler] interface for *Theme.\nfunc (t *Theme) UnmarshalText(b []byte) (err error) {\n\tswitch string(b) {\n\tcase \"auto\":\n\t\t*t = ThemeAuto\n\tcase \"dark\":\n\t\t*t = ThemeDark\n\tcase \"light\":\n\t\t*t = ThemeLight\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid theme %q, supported: %q, %q, %q\", b, ThemeAuto, ThemeDark, ThemeLight)\n\t}\n\n\treturn nil\n}\n\n// profileJSON is an object for /control/profile and /control/profile/update\n// endpoints.\ntype profileJSON struct {\n\tName     string `json:\"name\"`\n\tLanguage string `json:\"language\"`\n\tTheme    Theme  `json:\"theme\"`\n}\n\n// handleGetProfile is the handler for GET /control/profile endpoint.\nfunc (web *webAPI) handleGetProfile(w http.ResponseWriter, r *http.Request) {\n\tctx := r.Context()\n\n\tvar name string","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/home/profilehttp.go#L15-L51","documentation":"Theme.UnmarshalText rejects a profile theme string that is not 'auto', 'dark', or 'light'. This runs whenever a profile JSON body is decoded — PUT /control/profile/update or reads of /control/profile bodies.","triggerScenarios":"PUT /control/profile/update with \"theme\": \"system\", \"themes\": \"dark \", or any casing other than the three exact lowercase values; encoding/json surfaces this as a SyntaxError wrapping this message.","commonSituations":"Third-party clients or scripts sending theme names the UI never produces, region-locale defaults like '暗色', or values from older API versions.","solutions":["Send exactly one of \"auto\", \"dark\", \"light\" (lowercase, no whitespace)","Validate the theme on the client before PUTing the profile","If integrating, treat unknown themes as 'auto' rather than forwarding raw user input"],"exampleFix":"// before\n{\"name\":\"admin\",\"theme\":\"system\"}\n\n// after\n{\"name\":\"admin\",\"theme\":\"auto\"}","handlingStrategy":"type-guard","validationCode":"var validThemes = map[string]bool{\"auto\": true, \"dark\": true, \"light\": true}\nif !validThemes[req.Theme] { req.Theme = \"auto\" }","typeGuard":"func isValidTheme(s string) bool {\n    switch s { case \"auto\", \"dark\", \"light\": return true }; return false\n}","tryCatchPattern":null,"preventionTips":["Send exact lowercase theme strings","Treat unknown client theme values as \"auto\" server-side before persisting"],"tags":["go","http-api","profile","theme","validation","json"],"backgroundTag":"enum-value-validation-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}