glanceapp/glance · error

invalid source

Error message

invalid source

What it means

Thrown by the releases widget's unmarshaling when a repository string contains a colon and the prefix before it is not one of the recognized sources. Recognized prefixes are exactly github, gitlab, codeberg, and dockerhub (lowercase); the suffix after the colon becomes the repository and the prefix selects the API. An unprefixed 'owner/repo' silently defaults to github.

Source

Thrown at internal/glance/widget-releases.go:149

	}

	parts := strings.SplitN(repository, ":", 2)
	if len(parts) == 1 {
		r.source = releaseSourceGithub
	} else if len(parts) == 2 {
		r.Repository = parts[1]

		switch parts[0] {
		case string(releaseSourceGithub):
			r.source = releaseSourceGithub
		case string(releaseSourceGitlab):
			r.source = releaseSourceGitlab
		case string(releaseSourceDockerHub):
			r.source = releaseSourceDockerHub
		case string(releaseSourceCodeberg):
			r.source = releaseSourceCodeberg
		default:
			return errors.New("invalid source")
		}
	}

	return nil
}

func fetchLatestReleases(requests []*releaseRequest) (appReleaseList, error) {
	job := newJob(fetchLatestReleaseTask, requests).withWorkers(20)
	results, errs, err := workerPoolDo(job)
	if err != nil {
		return nil, err
	}

	var failed int

	releases := make(appReleaseList, 0, len(requests))

	for i := range results {

View on GitHub (pinned to 91324e8de7)

Solutions

  1. Use one of the exact lowercase prefixes: github:, gitlab:, dockerhub:, or codeberg:
  2. For GitHub repos, drop the prefix entirely ('owner/repo' defaults to github)
  3. For registries whose image name contains a colon (port numbers), note that the first colon is parsed as the source separator; use the dockerhub: prefix with the remainder intact if it matches that shape

Example fix

# before
- type: releases
  repositories:
    - docker:library/nginx

# after
- type: releases
  repositories:
    - dockerhub:library/nginx
Defensive patterns

Strategy: type-guard

Validate before calling

SOURCES = {'github', 'gitlab', 'codeberg', 'dockerhub'}
for r in w.get('repositories', []):
    repo = r if isinstance(r, str) else r.get('repository', '')
    if ':' in repo and repo.split(':', 1)[0].lower() not in SOURCES:
        raise ValueError(f"unknown source prefix in {repo!r}; valid: {sorted(SOURCES)}")

Type guard

const SOURCES = new Set(['github', 'gitlab', 'codeberg', 'dockerhub']);
function hasValidSource(repo: string): boolean {
  const i = repo.indexOf(':');
  if (i === -1) return true; // defaults to github
  return SOURCES.has(repo.slice(0, i));
}

Prevention

When it happens

Trigger: A repository entry like 'gitea:owner/repo', 'gh:owner/repo', 'docker:owner/repo', or any capitalized prefix like 'Gitlab:owner/repo'. Any single-colon string whose prefix is not in the switch hits the default case.

Common situations: Assuming 'docker:' works as shorthand for dockerhub; using a self-hosted Gitea/Forgejo instance and guessing a prefix; capitalizing the source name; entries that legitimately contain a colon in the repo name (dockerhub images with registry ports, e.g. 'registry.local:5000/team/app').

Related errors


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