{"record":{"id":"ee2eca73ada105f7","repo":"glanceapp/glance","slug":"repository-is-required","errorCode":null,"errorMessage":"repository is required","messagePattern":"repository is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/glance/widget-releases.go","lineNumber":127,"sourceCode":"\n\tsource releaseSource\n\ttoken  *string\n}\n\nfunc (r *releaseRequest) UnmarshalYAML(node *yaml.Node) error {\n\ttype releaseRequestAlias releaseRequest\n\talias := (*releaseRequestAlias)(r)\n\tvar repository string\n\n\tif err := node.Decode(&repository); err != nil {\n\t\tif err := node.Decode(alias); err != nil {\n\t\t\treturn fmt.Errorf(\"could not umarshal repository into string or struct: %v\", err)\n\t\t}\n\t}\n\n\tif r.Repository == \"\" {\n\t\tif repository == \"\" {\n\t\t\treturn errors.New(\"repository is required\")\n\t\t} else {\n\t\t\tr.Repository = repository\n\t\t}\n\t}\n\n\tparts := strings.SplitN(repository, \":\", 2)\n\tif len(parts) == 1 {\n\t\tr.source = releaseSourceGithub\n\t} else if len(parts) == 2 {\n\t\tr.Repository = parts[1]\n\n\t\tswitch parts[0] {\n\t\tcase string(releaseSourceGithub):\n\t\t\tr.source = releaseSourceGithub\n\t\tcase string(releaseSourceGitlab):\n\t\t\tr.source = releaseSourceGitlab\n\t\tcase string(releaseSourceDockerHub):\n\t\t\tr.source = releaseSourceDockerHub","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/glanceapp/glance/blob/91324e8de762702e97b0ac5c8e36271d644d8642/internal/glance/widget-releases.go#L109-L145","documentation":"Thrown by the releases widget's custom YAML unmarshaling (UnmarshalYAML on releaseRequest) when neither the struct's repository field nor a bare string form of the widget entry provides a repository. The field is polymorphic: it accepts either 'owner/repo' shorthand or a mapping with repository:; if both decode to empty the entry has nothing to track.","triggerScenarios":"A releases widget whose repositories list contains an entry like '- repository:' (empty value) or an empty mapping '- {}'; a template/anchor that expands to an empty string; a misspelled key (repo:, name:) inside the mapping form.","commonSituations":"Listing repositories as mappings and omitting the repository key on one entry; commenting out a repository but leaving the list item; YAML anchors referencing an empty default.","solutions":["Give each entry a repository value: either '- owner/repo' shorthand or a mapping with repository: owner/repo","Use the prefixed form 'gitlab:owner/repo', 'dockerhub:owner/repo', or 'codeberg:owner/repo' when the source is not GitHub","Remove empty entries from the list"],"exampleFix":"# before\n- type: releases\n  repositories:\n    - repository:\n\n# after\n- type: releases\n  repositories:\n    - go-glance/glance","handlingStrategy":"validation","validationCode":"for r in w.get('repositories', []):\n    repo = r if isinstance(r, str) else r.get('repository', '')\n    if not repo:\n        raise ValueError('every releases entry needs owner/repo (string or repository: key)')","typeGuard":"function isReleaseEntry(v: unknown): boolean {\n  if (typeof v === 'string') return v.trim().length > 0;\n  if (typeof v === 'object' && v !== null) {\n    return typeof (v as any).repository === 'string' && (v as any).repository.length > 0;\n  }\n  return false;\n}","tryCatchPattern":null,"preventionTips":["Prefer the shorthand string form '- owner/repo'; it is harder to leave half-empty","Generate repository lists from code rather than hand-editing","Remove list items entirely when retiring a repo instead of blanking the value"],"tags":["config","yaml","releases","validation"],"backgroundTag":null,"analyzedSha":"91324e8de762702e97b0ac5c8e36271d644d8642","analyzedAt":"2026-08-15T14:12:54.279Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}