{"record":{"id":"048f493c52b2b406","repo":"goharbor/harbor","slug":"tencent-tcr-prepareforpush-the-namespace-of-reso","errorCode":null,"errorMessage":"[tencent-tcr.PrepareForPush] the namespace of resource cannot be null","messagePattern":"\\[tencent-tcr\\.PrepareForPush\\] the namespace of resource cannot be null","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/reg/adapter/tencentcr/adapter.go","lineNumber":221,"sourceCode":"\t\tSupportedTriggers: []string{\n\t\t\tmodel.TriggerTypeManual,\n\t\t\tmodel.TriggerTypeScheduled,\n\t\t},\n\t}\n\treturn\n}\n\nfunc (a *adapter) PrepareForPush(resources []*model.Resource) (err error) {\n\tlog.Debugf(\"[tencent-tcr.PrepareForPush]\")\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(\"[tencent-tcr.PrepareForPush] the metadata of resource cannot be null\")\n\t\t}\n\t\tif resource.Metadata.Repository == nil {\n\t\t\treturn errors.New(\"[tencent-tcr.PrepareForPush] 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(\"[tencent-tcr.PrepareForPush] the name of the namespace cannot be null\")\n\t\t}\n\t\tvar paths = strings.Split(resource.Metadata.Repository.Name, \"/\")\n\t\tvar namespace = paths[0]\n\t\tvar repository = path.Join(paths[1:]...)\n\n\t\tlog.Debugf(\"[tencent-tcr.PrepareForPush.createPrivateNamespace] namespace=%s\", namespace)\n\t\terr = a.createPrivateNamespace(namespace)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tlog.Debugf(\"[tencent-tcr.PrepareForPush.createRepository] namespace=%s, repository=%s\", namespace, repository)\n\t\terr = a.createRepository(namespace, repository)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/reg/adapter/tencentcr/adapter.go#L203-L239","documentation":"Returned by the Tencent TCR adapter's PrepareForPush (src/pkg/reg/adapter/tencentcr/adapter.go:221) when resource.Metadata exists but resource.Metadata.Repository is nil. The adapter splits Repository.Name into namespace and repository to call createPrivateNamespace/createRepository, so a nil Repository pointer is rejected before any Tencent API call.","triggerScenarios":"Calling tencentcr PrepareForPush with ResourceMetadata that omits the Repository field (only Vtags/Artifact set).","commonSituations":"Tag-oriented metadata reused for push; struct clones dropping fields; builders where Repository assignment sits in a rarely-taken branch.","solutions":["Set Metadata.Repository with a non-empty Name for every pushed resource.","Run the slice-wide validation helper first to get the failing index.","Copy the whole Metadata (including Repository pointer) when cloning source resources.","Add a builder unit test asserting Repository != nil."],"exampleFix":"// before\nMetadata: &model.ResourceMetadata{Vtags: []string{\"v1\"}},\n\n// after\nMetadata: &model.ResourceMetadata{\n    Repository: &model.Repository{Name: \"myns/myrepo\"},\n    Vtags:     []string{\"v1\"},\n},","handlingStrategy":"validation","validationCode":"for i, r := range resources {\n\tif r == nil || r.Metadata == nil || r.Metadata.Repository == nil {\n\t\treturn fmt.Errorf(\"resources[%d]: missing resource/metadata/repository\", i)\n\t}\n}","typeGuard":"func hasRepository(r *model.Resource) bool {\n\treturn r != nil && r.Metadata != nil && r.Metadata.Repository != nil\n}","tryCatchPattern":"if err := a.PrepareForPush(resources); err != nil {\n\tif strings.Contains(err.Error(), \"namespace of resource cannot be null\") {\n\t\t// set Metadata.Repository before retry\n\t}\n\treturn err\n}","preventionTips":["Clone Metadata wholesale when copying resources.","Builder tests assert Repository non-nil."],"tags":["go","tencent-tcr","replication","validation","nil-check"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}