{"record":{"id":"88522510976f290b","repo":"glanceapp/glance","slug":"no-request-url-placeholder-specified","errorCode":null,"errorMessage":"no `{REQUEST-URL}` placeholder specified","messagePattern":"no `(.+?)` placeholder specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/widget-reddit.go","lineNumber":81,"sourceCode":"\t}\n\n\tif widget.CollapseAfter == 0 || widget.CollapseAfter < -1 {\n\t\twidget.CollapseAfter = 5\n\t}\n\n\ts := widget.SortBy\n\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}","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-reddit.go#L63-L99","documentation":"Thrown by the reddit widget's initialize() when request-url-template is non-empty but does not contain the literal {REQUEST-URL} placeholder. The template exists to wrap/redirect the underlying Reddit request URL (e.g. through an SSRF-friendly mirror or proxy), and Glance performs a plain substring check for the placeholder it will substitute.","triggerScenarios":"request-url-template: https://mirror.example.com/reddit (missing the placeholder); using single braces with spaces like { REQUEST-URL }; using a Go-template syntax like {{.RequestURL}} instead of the literal {REQUEST-URL}.","commonSituations":"Routing Reddit traffic through a mirror or proxy that changed its URL scheme; adapting a template from an older example with different placeholder casing (the check is case-sensitive).","solutions":["Include the exact literal {REQUEST-URL} in the template, e.g. request-url-template: 'https://mirror.example.com?url={REQUEST-URL}'","Remove request-url-template entirely if direct access to reddit.com works for you"],"exampleFix":"# before\n- type: reddit\n  subreddit: selfhosted\n  request-url-template: https://mirror.example.com/reddit\n\n# after\n- type: reddit\n  subreddit: selfhosted\n  request-url-template: 'https://mirror.example.com?url={REQUEST-URL}'","handlingStrategy":"validation","validationCode":"PLACEHOLDER = '{REQUEST-URL}'\ntmpl = w.get('request-url-template')\nif tmpl is not None and PLACEHOLDER not in tmpl:\n    raise ValueError(f'request-url-template must contain the literal {PLACEHOLDER}')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["The placeholder is case-sensitive and brace-exact: {REQUEST-URL}","Omit request-url-template unless you proxy Reddit traffic","Test proxy templates with curl once before deploying, substituting a real Reddit URL for the placeholder"],"tags":["config","yaml","reddit","proxy","validation"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}