{"record":{"id":"f7d51a2325a7b864","repo":"glanceapp/glance","slug":"initializing-primary-request-v","errorCode":null,"errorMessage":"initializing primary request: %v","messagePattern":"initializing primary request: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/widget-custom-api.go","lineNumber":55,"sourceCode":"\thttpRequest        *http.Request        `yaml:\"-\"`\n}\n\ntype customAPIWidget struct {\n\twidgetBase        `yaml:\",inline\"`\n\t*CustomAPIRequest `yaml:\",inline\"`             // the primary request\n\tSubrequests       map[string]*CustomAPIRequest `yaml:\"subrequests\"`\n\tOptions           customAPIOptions             `yaml:\"options\"`\n\tTemplate          string                       `yaml:\"template\"`\n\tFrameless         bool                         `yaml:\"frameless\"`\n\tcompiledTemplate  *template.Template           `yaml:\"-\"`\n\tCompiledHTML      template.HTML                `yaml:\"-\"`\n}\n\nfunc (widget *customAPIWidget) initialize() error {\n\twidget.withTitle(\"Custom API\").withCacheDuration(1 * time.Hour)\n\n\tif err := widget.CustomAPIRequest.initialize(); err != nil {\n\t\treturn fmt.Errorf(\"initializing primary request: %v\", err)\n\t}\n\n\tfor key := range widget.Subrequests {\n\t\tif err := widget.Subrequests[key].initialize(); err != nil {\n\t\t\treturn fmt.Errorf(\"initializing subrequest %q: %v\", key, err)\n\t\t}\n\t}\n\n\tif widget.Template == \"\" {\n\t\treturn errors.New(\"template is required\")\n\t}\n\n\tcompiledTemplate, err := template.New(\"\").Funcs(customAPITemplateFuncs).Parse(widget.Template)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing template: %w\", err)\n\t}\n\n\twidget.compiledTemplate = compiledTemplate","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-custom-api.go#L37-L73","documentation":"Returned by customAPIWidget.initialize when the widget's primary CustomAPIRequest.initialize() fails. That initializer validates the request definition — most notably the body-type must be json or string and the body must marshal — so this wraps config-level mistakes in the widget's top-level request block.","triggerScenarios":"The main request block of a custom-api widget has an invalid body-type, a body that cannot be marshaled, or another failed validation performed by CustomAPIRequest.initialize().","commonSituations":"YAML indentation puts a subrequest-only field on the primary request; body-type typo like \"JSON\" or \"text\"; body containing a value json.Marshal rejects.","solutions":["Inspect the primary request block of the custom-api widget: url, body-type, body fields.","Set body-type: json only when body is a YAML mapping/list; use string only for a plain string body.","Re-check YAML indentation so subrequests: live under the widget, not merged into the primary request.","Fix the underlying cause reported by the wrapped error — this message only adds the \"primary request\" context."],"exampleFix":"# before\n- type: custom-api\n  url: https://example.com/api\n  body-type: text\n\n# after\n- type: custom-api\n  url: https://example.com/api\n  body-type: json","handlingStrategy":"validation","validationCode":"// sanity-check a custom-api primary request before glance loads it\nfunc checkCustomAPIPrimary(r CustomAPIRequest) error {\n    if r.URL == \"\" {\n        return errors.New(\"custom-api: url is required\")\n    }\n    if r.BodyType != \"\" && r.BodyType != \"json\" && r.BodyType != \"string\" {\n        return fmt.Errorf(\"custom-api: body-type must be json or string, got %q\", r.BodyType)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := widget.initialize(); err != nil {\n    // initialization errors are config bugs: fail fast, show the widget as errored\n    widget.withError(err) // or log and skip rendering this widget\n}","preventionTips":["Validate custom-api blocks with a config linter before deploying pages.","Mirror the primary request shape from working examples in the docs.","Treat 'initializing primary request' as a config error, not a runtime/network one."],"tags":["config","custom-api","widget"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}