{"record":{"id":"8174c414dcefa285","repo":"goharbor/harbor","slug":"the-resource-cannot-be-null-8174c4","errorCode":null,"errorMessage":"the resource cannot be null","messagePattern":"the resource cannot be null","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/reg/adapter/tencentcr/adapter.go","lineNumber":215,"sourceCode":"\t\t\t},\n\t\t\t{\n\t\t\t\tType:  model.FilterTypeTag,\n\t\t\t\tStyle: model.FilterStyleTypeText,\n\t\t\t},\n\t\t},\n\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","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/reg/adapter/tencentcr/adapter.go#L197-L233","documentation":"Returned by the Tencent TCR adapter's PrepareForPush (src/pkg/reg/adapter/tencentcr/adapter.go:215) when the resources slice contains a nil *model.Resource element. The method pre-creates the TCR namespace and repository before pushing, and dereferences each resource in the loop, so a nil entry is rejected first.","triggerScenarios":"Calling tencentcr PrepareForPush with a slice built by appending nil (e.g. conditional fetch results) instead of fully-formed resources.","commonSituations":"Custom transfer code appending placeholders on failure; sparse slices after filtering; refactors that introduce nil defaults; test tables with nil rows reaching shared code.","solutions":["Stop appending nil at the construction site; fail fast on fetch errors instead.","Pre-validate the slice (see validationCode) to report the failing index.","Keep one builder for resources shared by tests and production.","Assert non-nil invariants in the pipeline's unit tests."],"exampleFix":"// before\nresources = append(resources, r) // r may be nil\n\n// after\nif r == nil {\n    return fmt.Errorf(\"fetch returned nil resource\")\n}\nresources = append(resources, r)","handlingStrategy":"validation","validationCode":"for i, r := range resources {\n\tif r == nil {\n\t\treturn fmt.Errorf(\"resources[%d] is nil\", i)\n\t}\n}","typeGuard":"func isUsableResource(r *model.Resource) bool { return r != nil }","tryCatchPattern":"if err := a.PrepareForPush(resources); err != nil {\n\tif strings.Contains(err.Error(), \"the resource cannot be null\") {\n\t\t// nil element: fix slice construction\n\t}\n\treturn err\n}","preventionTips":["Abort on nil fetch results instead of appending placeholders.","Validate slices at pipeline boundaries.","Builder-based tests avoid nil fixtures."],"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"}