glanceapp/glance · error
%s widget: %v
Error message
%s widget: %v
What it means
This error wraps any failure that occurs while a widget defined in the glance configuration is being initialized. formatWidgetInitError prefixes the widget's type (from w.GetType()) to the underlying error so the user knows which widget in the YAML failed. It is not an error condition itself; the root cause is always the wrapped error after the colon.
Source
Thrown at internal/glance/config.go:237
}
if !filepath.IsAbs(filePath) {
return "", false, fmt.Errorf("readFileFromEnv: file path %s is not absolute", filePath)
}
fileContents, err := os.ReadFile(filePath)
if err != nil {
return "", false, fmt.Errorf("readFileFromEnv: reading file from %s: %v", variableName, err)
}
return strings.TrimSpace(string(fileContents)), false, nil
default:
return "", true, nil
}
}
func formatWidgetInitError(err error, w widget) error {
return fmt.Errorf("%s widget: %v", w.GetType(), err)
}
var configIncludePattern = regexp.MustCompile(`(?m)^([ \t]*)(?:-[ \t]*)?(?:!|\$)include:[ \t]*(.+)$`)
func parseYAMLIncludes(mainFilePath string) ([]byte, map[string]struct{}, error) {
return recursiveParseYAMLIncludes(mainFilePath, nil, 0)
}
func recursiveParseYAMLIncludes(mainFilePath string, includes map[string]struct{}, depth int) ([]byte, map[string]struct{}, error) {
if depth > CONFIG_INCLUDE_RECURSION_DEPTH_LIMIT {
return nil, nil, fmt.Errorf("recursion depth limit of %d reached", CONFIG_INCLUDE_RECURSION_DEPTH_LIMIT)
}
mainFileContents, err := os.ReadFile(mainFilePath)
if err != nil {
return nil, nil, fmt.Errorf("reading %s: %w", mainFilePath, err)
}
View on GitHub (pinned to 91324e8de7)
Solutions
- Read the text after 'widget:' — it names the exact widget type and the underlying cause; fix that field in glance.yml
- Compare the widget's YAML block against the widget's documentation for required options
- If the error mentions a URL or parse failure, verify the value's format (scheme, escaping of colons in YAML)
- After a version upgrade, check the changelog for renamed/removed widget options
Example fix
# before
type: feed
widgets:
- type: feed
# after (missing option added)
type: feed
widgets:
- type: feed
feed-url: https://example.com/rss Defensive patterns
Strategy: try-catch
Validate before calling
// Before applying config, dry-parse it and report per-widget errors:
if _, err := glance.ParseAndValidateConfig(bytes); err != nil {
log.Printf("config rejected: %v", err)
} Try / catch
err := cfg.Apply()
if err != nil {
if strings.HasSuffix(err.Error(), "widget") || strings.Contains(err.Error(), " widget: ") {
// extract widget type from prefix, underlying cause from suffix
log.Printf("widget init failed: %v", err)
}
return err
} Prevention
- Validate config in CI with a parse step before deploying
- Use glance's config check / hot-reload to surface widget errors without downtime
- Keep widget blocks minimal and copied from current docs
When it happens
Trigger: Glance parses a page's widgets, constructs each widget by type (e.g. feed via type: feed), and the widget's constructor returns an error — for example a required field missing (feed without feed-url), an invalid URL, or an unparsable option. The wrapper fires during config parse/apply at startup or on config hot-reload.
Common situations: A typo in a widget field name, forgetting a mandatory option like feed-url, putting a widget's settings under the wrong nesting level, or upgrading glance so a widget option changed its expected format. On config reload this makes the offending widget render as an error card or abort the reload.
Related errors
- recursion depth limit of %d reached
- no pages configured
- user has no name
- page %d has no name
- page %d has no columns
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/2e7137500d956bc1.
Report an issue: GitHub.