glanceapp/glance · error
could not umarshal repository into string or struct: %v
Error message
could not umarshal repository into string or struct: %v
What it means
Thrown by releaseRequest.UnmarshalYAML (internal/glance/widget-releases.go:121) when a releases-widget entry in glance.yml is neither a plain string nor a valid releaseRequest struct. The custom unmarshaller first tries node.Decode(&repository) (string form like 'go-gitea/gitea'), and on failure tries node.Decode(alias) (map form with repository:/token:/show-source keys); if both fail, this error wraps the struct-decode error.
Source
Thrown at internal/glance/widget-releases.go:121
return r
}
type releaseRequest struct {
IncludePreleases bool `yaml:"include-prereleases"`
Repository string `yaml:"repository"`
source releaseSource
token *string
}
func (r *releaseRequest) UnmarshalYAML(node *yaml.Node) error {
type releaseRequestAlias releaseRequest
alias := (*releaseRequestAlias)(r)
var repository string
if err := node.Decode(&repository); err != nil {
if err := node.Decode(alias); err != nil {
return fmt.Errorf("could not umarshal repository into string or struct: %v", err)
}
}
if r.Repository == "" {
if repository == "" {
return errors.New("repository is required")
} else {
r.Repository = repository
}
}
parts := strings.SplitN(repository, ":", 2)
if len(parts) == 1 {
r.source = releaseSourceGithub
} else if len(parts) == 2 {
r.Repository = parts[1]
switch parts[0] {View on GitHub (pinned to 91324e8de7)
Solutions
- Use the plain string form: '- go-gitea/gitea' or with prefix '- github:go-gitea/gitea'
- Or use the struct form with the exact key 'repository': '- repository: go-gitea/gitea' on its own line, optional 'token:' and 'show-source:' siblings
- Check the wrapped error (%v) — it names the struct field that failed to decode
- Validate the YAML block with yamllint or a YAML linter before restarting Glance
Example fix
// before (glance.yml)
widget:
type: releases
repositories:
- repo: go-gitea/gitea # wrong key
- [gitea, gitea] # sequence, not a string
// after
widget:
type: releases
repositories:
- go-gitea/gitea
- repository: go-gitea/gitea
show-source: true Defensive patterns
Strategy: validation
Validate before calling
// Validate a releases entry before it reaches UnmarshalYAML
func isValidReleaseEntry(node yaml.Node) bool {
return node.Kind == yaml.ScalarNode || node.Kind == yaml.MappingNode
} Try / catch
if err := widget.Initialize(); err != nil {
if strings.Contains(err.Error(), "could not umarshal repository") {
// config error: point user at the failing releases entry, fail fast at startup
}
} Prevention
- Use linters on glance.yml
- Keep entries in the documented string or struct forms only
- Check startup logs; config errors surface immediately at page render
When it happens
Trigger: A YAML node that is a sequence (repository: [gitea, gitea]), a scalar of wrong type (repository: 12), a map with unknown/misspelled keys or wrong value types (repository: { repo: x } instead of repository: x), or mixed syntax combining string and map forms incorrectly.
Common situations: Typing 'repo:' instead of 'repository:', quoting mistakes turning a map into a string, copying example config with placeholder values, or indenting the string form so YAML parses it as a nested map.
Related errors
- repository is required
- invalid source
- URL is required
- nested groups are not supported
- split columns inside of groups are not supported
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/382fc2e414739acf.
Report an issue: GitHub.