{"record":{"id":"dbc8f64b38192f38","repo":"glanceapp/glance","slug":"source-is-required","errorCode":null,"errorMessage":"source is required","messagePattern":"source is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/widget-iframe.go","lineNumber":23,"sourceCode":"\t\"fmt\"\n\t\"html/template\"\n\t\"net/url\"\n)\n\nvar iframeWidgetTemplate = mustParseTemplate(\"iframe.html\", \"widget-base.html\")\n\ntype iframeWidget struct {\n\twidgetBase `yaml:\",inline\"`\n\tcachedHTML template.HTML `yaml:\"-\"`\n\tSource     string        `yaml:\"source\"`\n\tHeight     int           `yaml:\"height\"`\n}\n\nfunc (widget *iframeWidget) initialize() error {\n\twidget.withTitle(\"IFrame\").withError(nil)\n\n\tif widget.Source == \"\" {\n\t\treturn errors.New(\"source is required\")\n\t}\n\n\tif _, err := url.Parse(widget.Source); err != nil {\n\t\treturn fmt.Errorf(\"parsing URL: %v\", err)\n\t}\n\n\tif widget.Height == 50 {\n\t\twidget.Height = 300\n\t} else if widget.Height < 50 {\n\t\twidget.Height = 50\n\t}\n\n\twidget.cachedHTML = widget.renderTemplate(widget, iframeWidgetTemplate)\n\n\treturn nil\n}\n\nfunc (widget *iframeWidget) Render() template.HTML {","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-iframe.go#L5-L41","documentation":"Thrown by the iframe widget's initialize() when the source field is empty. The widget renders a single <iframe src=...>, so source is the only required field; it is parsed with url.Parse (which almost never fails) and the height defaults to 300 when left at 50 or clamped to a minimum of 50.","triggerScenarios":"A widget of type: iframe with no source: key, source commented out, or misspelled (src:, url:); a source value that YAML parses as null.","commonSituations":"Embedding an internal tool and removing the source while iterating; indentation errors nesting source under another key.","solutions":["Set source: to the URL to embed, e.g. source: https://example.com/embed","Check the key is exactly 'source' and correctly indented at widget level","Optionally set height: (values below 50 clamp to 50; unset defaults to 300)"],"exampleFix":"# before\n- type: iframe\n  height: 400\n\n# after\n- type: iframe\n  source: https://example.com/embed\n  height: 400","handlingStrategy":"validation","validationCode":"if w['type'] == 'iframe' and not w.get('source'):\n    raise ValueError('iframe widget requires source')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the key 'source', not src/url","Set an explicit height when embedding tall pages (minimum is 50, default 300)","Confirm the target site allows iframe embedding (X-Frame-Options/CSP) before wiring it in"],"tags":["config","yaml","iframe","validation"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}