{"record":{"id":"fbd8f02371dda3ed","repo":"amir20/dozzle","slug":"empty-image-reference","errorCode":null,"errorMessage":"empty image reference","messagePattern":"empty image reference","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/imagecheck/reference.go","lineNumber":90,"sourceCode":"\t\treturn \"http\"\n\t}\n\treturn \"https\"\n}\n\n// manifestURL is the v2 manifest endpoint for this reference.\nfunc (r Reference) manifestURL() string {\n\ttarget := r.Tag\n\tif target == \"\" {\n\t\ttarget = r.Digest\n\t}\n\treturn fmt.Sprintf(\"%s://%s/v2/%s/manifests/%s\", r.scheme(), r.host(), r.Repository, target)\n}\n\n// ParseReference splits an image reference into its registry, repository and\n// tag/digest parts, applying Docker's implicit defaults.\nfunc ParseReference(ref string) (Reference, error) {\n\tif ref == \"\" {\n\t\treturn Reference{}, fmt.Errorf(\"empty image reference\")\n\t}\n\n\tremainder := ref\n\tvar digest string\n\t// A digest always trails the reference and may follow a tag, as in\n\t// \"nginx:1.25@sha256:abc...\".\n\tif i := strings.Index(remainder, \"@\"); i != -1 {\n\t\tdigest = remainder[i+1:]\n\t\tremainder = remainder[:i]\n\t\tif digest == \"\" {\n\t\t\treturn Reference{}, fmt.Errorf(\"invalid image reference %q: empty digest\", ref)\n\t\t}\n\t}\n\n\tregistry := defaultRegistry\n\t// The first path component is a registry only when it looks like a host:\n\t// it contains a dot or port separator, or is localhost. Otherwise it is a\n\t// Docker Hub namespace such as \"amir20\" in \"amir20/dozzle\".","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/imagecheck/reference.go#L72-L108","documentation":"ParseReference rejects an empty string before doing any parsing, since an image reference must at minimum name a repository. Returning an empty image reference means the caller passed \"\" into the image update checker.","triggerScenarios":"Calling ParseReference(\"\") directly, or indirectly via Check/digestsForRepository when a container's image field is empty (image never set or stripped by a marshaling bug).","commonSituations":"A container record with a blank image property (e.g. a manually constructed container in tests), config where the image key was omitted, or empty string from a trimmed env/config value.","solutions":["Check that the container/image actually has a non-empty image reference before calling ParseReference","Fix the source of the empty value (container config, env var, test fixture)","Guard: if ref == \"\" { skip the update check } instead of parsing"],"exampleFix":"// before\nif err := imagecheck.Check(container.Image); err != nil { ... }\n// after\nif container.Image == \"\" {\n    return nil // nothing to check\n}\nif err := imagecheck.Check(container.Image); err != nil { ... }","handlingStrategy":"validation","validationCode":"if image == \"\" {\n    return nil // or skip update check\n}","typeGuard":"func hasImage(c Container) bool { return strings.TrimSpace(c.Image) != \"\" }","tryCatchPattern":"if err := imagecheck.Check(ref); err != nil {\n    if err.Error() == \"empty image reference\" {\n        return nil // nothing to verify\n    }\n    return err\n}","preventionTips":["Never construct containers with an empty Image field","Trim and default config/env image values at load time","Skip update checks when the image is unknown instead of parsing"],"tags":["image","reference-parsing","empty-input","validation"],"backgroundTag":"empty-required-field","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}