{"record":{"id":"95a86b244a128706","repo":"glanceapp/glance","slug":"application-name-client-id-and-client-secret-are","errorCode":null,"errorMessage":"application name, client ID and client secret are required","messagePattern":"application name, client ID and client secret are required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/widget-reddit.go","lineNumber":88,"sourceCode":"\tif s != \"hot\" && s != \"new\" && s != \"top\" && s != \"rising\" {\n\t\twidget.SortBy = \"hot\"\n\t}\n\n\tp := widget.TopPeriod\n\tif p != \"hour\" && p != \"day\" && p != \"week\" && p != \"month\" && p != \"year\" && p != \"all\" {\n\t\twidget.TopPeriod = \"day\"\n\t}\n\n\tif widget.RequestURLTemplate != \"\" {\n\t\tif !strings.Contains(widget.RequestURLTemplate, \"{REQUEST-URL}\") {\n\t\t\treturn errors.New(\"no `{REQUEST-URL}` placeholder specified\")\n\t\t}\n\t}\n\n\ta := &widget.AppAuth\n\tif a.Name != \"\" || a.ID != \"\" || a.Secret != \"\" {\n\t\tif a.Name == \"\" || a.ID == \"\" || a.Secret == \"\" {\n\t\t\treturn errors.New(\"application name, client ID and client secret are required\")\n\t\t}\n\t\ta.enabled = true\n\t}\n\n\twidget.\n\t\twithTitle(\"r/\" + widget.Subreddit).\n\t\twithTitleURL(\"https://www.reddit.com/r/\" + widget.Subreddit + \"/\").\n\t\twithCacheDuration(30 * time.Minute)\n\n\treturn nil\n}\n\nfunc (widget *redditWidget) update(ctx context.Context) {\n\tposts, err := widget.fetchSubredditPosts()\n\tif !widget.canContinueUpdateAfterHandlingErr(err) {\n\t\treturn\n\t}\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-reddit.go#L70-L106","documentation":"Thrown by the reddit widget's initialize() when app-auth is partially filled in. If any of name, id, or secret is set, all three must be set; app-auth is opt-in for OAuth-based Reddit API access with higher rate limits than anonymous JSON endpoints. Glance enables app auth only when the triple is complete.","triggerScenarios":"An app-auth block with only id and secret (missing name); only name set (pasting the app name first and saving); a secret that YAML decodes as empty (quoted-empty or null); whitespace-only values.","commonSituations":"Creating a Reddit 'script' app and copying two of the three values; rotating the client secret and leaving it blank during the edit; assuming name is optional because it is just a label.","solutions":["Fill in all three keys under app-auth: name (any label), id (client ID), secret (client secret) from your Reddit app settings","Double-check indentation so all three keys sit directly under app-auth","If you do not want app auth, remove the entire app-auth block rather than leaving partial values"],"exampleFix":"# before\napp-auth:\n  id: abc123\n  secret: xyz789\n\n# after\napp-auth:\n  name: my-glance-app\n  id: abc123\n  secret: xyz789","handlingStrategy":"validation","validationCode":"aa = w.get('app-auth')\nif aa is not None:\n    missing = [k for k in ('name', 'id', 'secret') if not aa.get(k)]\n    if missing:\n        raise ValueError(f'app-auth is partial; missing: {missing}')","typeGuard":"type AppAuth = { name: string; id: string; secret: string };\nfunction isCompleteAppAuth(v: unknown): v is AppAuth {\n  if (typeof v !== 'object' || v === null) return false;\n  const o = v as Record<string, unknown>;\n  return ['name', 'id', 'secret'].every(k => typeof o[k] === 'string' && o[k].length > 0);\n}","tryCatchPattern":null,"preventionTips":["Create the Reddit app first, then fill all three app-auth keys in one edit","Inject the secret from a secrets manager instead of hand-editing, so blanks fail at deploy time","Remove the whole app-auth block if anonymous access is enough"],"tags":["config","yaml","reddit","authentication","validation"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}