glanceapp/glance · error

parsing URL: %v

Error message

parsing URL: %v

What it means

Thrown during extension widget initialization when url.Parse rejects the configured URL. Go's url.Parse only errors on control characters or malformed escapes, so this is almost always a config typo. Note that url.Parse accepts relative URLs, so a missing scheme passes validation but fails later at fetch time.

Source

Thrown at internal/glance/widget-extension.go:39

	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,
	})

	widget.canContinueUpdateAfterHandlingErr(err)

	widget.Extension = extension

View on GitHub (pinned to 91324e8de7)

Solutions

  1. Rewrite the url: value by hand, quoted, in the extension widget config
  2. Percent-encode literal % as %25 and any spaces
  3. Include the scheme (https://) even though validation alone does not require it

Example fix

# before
- type: extension
  url: https://example.com/ext%zz
# after
- type: extension
  url: "https://example.com/ext%25zz"
Defensive patterns

Strategy: validation

Validate before calling

func validateExtensionURL(raw string) error {
    if raw == "" {
        return errors.New("URL is required")
    }
    u, err := url.Parse(raw)
    if err != nil {
        return fmt.Errorf("parsing URL: %v", err)
    }
    if u.Scheme != "http" && u.Scheme != "https" {
        return fmt.Errorf("URL %q must start with http:// or https://", raw)
    }
    return nil
}

Type guard

func isHTTPURL(raw string) bool {
    u, err := url.Parse(raw)
    return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
}

Try / catch

if err := widget.initialize(); err != nil {
    slog.Error("extension widget disabled", "error", err)
    widget.withError(err) // render config error in place of the widget
}

Prevention

When it happens

Trigger: Extension widget's url: field contains a control character, invalid percent-escape (e.g. '%zz'), or is otherwise unparseable.

Common situations: Copy-pasted URL with hidden characters; YAML multi-line or special-character handling corrupting the value; percent signs in the URL not encoded.

Related errors


AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15). Data as JSON: /api/errors/06838249b8b86579. Report an issue: GitHub.