goharbor/harbor · error
the resource cannot be null
Error message
the resource cannot be null
What it means
Returned by the JFrog Artifactory adapter's PrepareForPush (src/pkg/reg/adapter/jfrog/adapter.go:120), which pre-creates local docker repositories in Artifactory before images are pushed. The loop over resources rejects any element that is a nil *model.Resource. It throws early because later code dereferences resource.Metadata unconditionally.
Source
Thrown at src/pkg/reg/adapter/jfrog/adapter.go:120
},
}
return
}
func newAdapter(registry *model.Registry) (adp.Adapter, error) {
return &adapter{
Adapter: native.NewAdapter(registry),
registry: registry,
client: newClient(registry),
}, nil
}
// PrepareForPush creates local docker repository in jfrog artifactory
func (a *adapter) PrepareForPush(resources []*model.Resource) error {
var namespaces []string
for _, resource := range resources {
if resource == nil {
return errors.New("the resource cannot be null")
}
if resource.Metadata == nil {
return errors.New("the metadata of resource cannot be null")
}
if resource.Metadata.Repository == nil {
return errors.New("the namespace of resource cannot be null")
}
if len(resource.Metadata.Repository.Name) == 0 {
return errors.New("the name of namespace cannot be null")
}
path := strings.Split(resource.Metadata.Repository.Name, "/")
if len(path) > 0 {
namespaces = append(namespaces, path[0])
}
}
repositories, err := a.listAllRepositories()
if err != nil {View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Find where the resource slice is built and stop appending nil entries — fail the fetch instead of inserting nil.
- Sanitize the slice before the call (see validationCode) so the offending index is reported.
- If a nil entry is legitimate 'skip' semantics in your code, filter it out before calling PrepareForPush.
- Upgrade/review your caller: upstream Harbor always passes fully-formed resources, so a nil element indicates a local bug.
Example fix
// before
for _, r := range fetched {
if r == nil {
resources = append(resources, nil) // placeholder, panics later or errors here
} else {
resources = append(resources, r)
}
}
// after
for _, r := range fetched {
if r == nil {
return fmt.Errorf("fetch returned a nil resource")
}
resources = append(resources, r)
} Defensive patterns
Strategy: validation
Validate before calling
for i, r := range resources {
if r == nil {
return fmt.Errorf("resources[%d] is nil; refusing to call PrepareForPush", i)
}
}
if err := jfrogAdapter.PrepareForPush(resources); err != nil { /* ... */ } Type guard
func isUsableResource(r *model.Resource) bool { return r != nil } Try / catch
if err := a.PrepareForPush(resources); err != nil {
if strings.Contains(err.Error(), "the resource cannot be null") {
// slice construction bug: log index and rebuild resources
}
return err
} Prevention
- Filter or reject nil entries when assembling the slice.
- Fail the whole transfer when any fetch returns nil rather than inserting placeholders.
- Lint for 'append(resources, nil)' patterns in review.
When it happens
Trigger: Calling PrepareForPush on the jfrog adapter with a nil element in the []*model.Resource slice, e.g. append(resources, nil) or a filter step that leaves nil placeholders.
Common situations: Custom transfer pipelines that append nil when an intermediate fetch fails instead of aborting; refactoring that introduces sparse slices; copy between registries where one artifact's metadata build failed silently.
Related errors
- the metadata of resource cannot be null
- the namespace of resource cannot be null
- the name of namespace cannot be null
- the name of the repository cannot be null
- the resource cannot be null
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/3401fde3edeed2a8.
Report an issue: GitHub.