{"record":{"id":"32668b5947212b06","repo":"goharbor/harbor","slug":"the-name-of-the-namespace-cannot-be-null","errorCode":null,"errorMessage":"the name of the namespace cannot be null","messagePattern":"the name of the namespace cannot be null","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/reg/adapter/quay/adapter.go","lineNumber":164,"sourceCode":"// PrepareForPush does the prepare work that needed for pushing/uploading the resource\n// eg: create the namespace or repository\nfunc (a *adapter) PrepareForPush(resources []*model.Resource) error {\n\tif !a.autoCreateNs {\n\t\treturn nil\n\t}\n\tnamespaces := []string{}\n\tfor _, resource := range resources {\n\t\tif resource == nil {\n\t\t\treturn errors.New(\"the resource cannot be null\")\n\t\t}\n\t\tif resource.Metadata == nil {\n\t\t\treturn errors.New(\"the metadata of resource cannot be null\")\n\t\t}\n\t\tif resource.Metadata.Repository == nil {\n\t\t\treturn errors.New(\"the namespace of resource cannot be null\")\n\t\t}\n\t\tif len(resource.Metadata.Repository.Name) == 0 {\n\t\t\treturn errors.New(\"the name of the namespace cannot be null\")\n\t\t}\n\t\tpaths := strings.Split(resource.Metadata.Repository.Name, \"/\")\n\t\tnamespace := paths[0]\n\t\tnamespaces = append(namespaces, namespace)\n\t}\n\n\tfor _, namespace := range namespaces {\n\t\terr := a.createNamespace(&model.Namespace{\n\t\t\tName: namespace,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"create namespace '%s' in Quay error: %v\", namespace, err)\n\t\t}\n\t\tlog.Debugf(\"namespace %s created\", namespace)\n\t}\n\treturn nil\n}\n","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/reg/adapter/quay/adapter.go#L146-L182","documentation":"Returned by the Quay adapter's PrepareForPush (src/pkg/reg/adapter/quay/adapter.go:164) when resource.Metadata.Repository.Name is the empty string. The adapter splits the name on \"/\" and takes paths[0] as the Quay namespace to create; an empty name yields an empty namespace, which the guard rejects before calling Quay's API.","triggerScenarios":"Calling quay PrepareForPush with a Repository struct whose Name was never set or was cleared by an override/template step.","commonSituations":"Destination repository templating that evaluates to empty; struct copies that drop Name; fixtures with &model.Repository{}; upstream data where the repository name failed to propagate during fetch.","solutions":["Ensure Name is a non-empty 'namespace/repository' string before the call.","Pre-validate with the helper below to report the offending index.","Test name-computation logic (rules/filters) against empty inputs.","Log resource.Metadata.Repository at the boundary when diagnosing replication failures."],"exampleFix":"// before\nRepository: &model.Repository{},\n\n// after\nRepository: &model.Repository{Name: \"myteam/\" + base}, // ensure non-empty","handlingStrategy":"validation","validationCode":"for i, r := range resources {\n\tif r == nil || r.Metadata == nil || r.Metadata.Repository == nil || r.Metadata.Repository.Name == \"\" {\n\t\treturn fmt.Errorf(\"resources[%d]: invalid resource\", i)\n\t}\n}","typeGuard":"func hasNonEmptyRepoName(rs []*model.Resource) bool {\n\tfor _, r := range rs {\n\t\tif r == nil || r.Metadata == nil || r.Metadata.Repository == nil || r.Metadata.Repository.Name == \"\" {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":"if err := a.PrepareForPush(resources); err != nil {\n\tif strings.Contains(err.Error(), \"name of the namespace cannot be null\") {\n\t\t// empty Repository.Name: set 'namespace/repo' and retry\n\t}\n\treturn err\n}","preventionTips":["Set Repository.Name explicitly from the source repository.","Test template/override code for empty outputs.","Validate the slice at the boundary."],"tags":["go","quay","replication","validation","empty-string"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}