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

  1. Use the plain string form: '- go-gitea/gitea' or with prefix '- github:go-gitea/gitea'
  2. Or use the struct form with the exact key 'repository': '- repository: go-gitea/gitea' on its own line, optional 'token:' and 'show-source:' siblings
  3. Check the wrapped error (%v) — it names the struct field that failed to decode
  4. 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

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


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