glanceapp/glance · error
URL is required
Error message
URL is required
What it means
Thrown by the extension widget's initialize() when no url field is set. Extensions are remote page fragments loaded from a URL (with a default 30-minute cache), so the URL is the only mandatory field; an unset one is rejected immediately.
Solutions
- Set url: to the extension fragment's address, e.g. url: https://example.com/extension.html
- Verify the key is exactly 'url' and at the widget's top level
- To actually disable an extension widget, remove or comment out the whole widget block instead of just the url
Example fix
# before
- type: extension
# url: https://example.com/fragment.html
parameters:
key: value
# after
- type: extension
url: https://example.com/fragment.html
parameters:
key: value Defensive patterns
Strategy: validation
Validate before calling
if w['type'] == 'extension' and not w.get('url'):
raise ValueError('extension widget requires url') Prevention
- Write the url first when adding an extension widget
- Disable extensions by removing the whole block, not by deleting one key
- Lint for required keys per widget type in CI
When it happens
Trigger: A widget of type: extension with only fallback-content-type, parameters, or headers configured; url misspelled (uri:, link:) or commented out; url present only in a copy of the widget that was renamed.
Common situations: Prototyping an extension entry and commenting the url out to 'disable' it; indentation placing url under parameters.
Related errors
- application name, client ID and client secret are required
- could not umarshal repository into string or struct
- hour-format must be either 12h or 24h
- invalid duration format
- invalid HSL color format
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/0dd2dce949ed8546.
Report an issue: GitHub.
Appendix: source
Thrown at internal/glance/widget-extension.go:35
const extensionWidgetDefaultTitle = "Extension"
type extensionWidget struct {
widgetBase `yaml:",inline"`
URL string `yaml:"url"`
FallbackContentType string `yaml:"fallback-content-type"`
Parameters queryParametersField `yaml:"parameters"`
Headers map[string]string `yaml:"headers"`
AllowHtml bool `yaml:"allow-potentially-dangerous-html"`
Extension extension `yaml:"-"`
cachedHTML template.HTML `yaml:"-"`
}
func (widget *extensionWidget) initialize() error {
widget.withTitle(extensionWidgetDefaultTitle).withCacheDuration(time.Minute * 30)
if widget.URL == "" {
return errors.New("URL is required")
}
if _, err := url.Parse(widget.URL); err != nil {
return fmt.Errorf("parsing URL: %v", err)
}
return nil
}
func (widget *extensionWidget) update(ctx context.Context) {
extension, err := fetchExtension(extensionRequestOptions{
URL: widget.URL,
FallbackContentType: widget.FallbackContentType,
Parameters: widget.Parameters,
Headers: widget.Headers,
AllowHtml: widget.AllowHtml,
})
View on GitHub (pinned to 91324e8de7)