{"record":{"id":"3e37155f80d5a06f","repo":"goharbor/harbor","slug":"bad-request-3e3715","errorCode":"BAD_REQUEST","errorMessage":"addition %s isn't supported","messagePattern":"addition (.+?) isn't supported","errorType":"error_code","errorClass":"lib/errors.Error","httpStatus":400,"severity":"error","filePath":"src/controller/artifact/processor/base/manifest.go","lineNumber":68,"sourceCode":"\t}\n\t// if no properties specified, populate all metadata into the ExtraAttrs\n\tif len(m.properties) == 0 {\n\t\tartifact.ExtraAttrs = metadata\n\t\treturn nil\n\t}\n\n\tif artifact.ExtraAttrs == nil {\n\t\tartifact.ExtraAttrs = map[string]any{}\n\t}\n\tfor _, property := range m.properties {\n\t\tartifact.ExtraAttrs[property] = metadata[property]\n\t}\n\treturn nil\n}\n\n// AbstractAddition abstracts the addition of artifact\nfunc (m *ManifestProcessor) AbstractAddition(_ context.Context, _ *artifact.Artifact, addition string) (*processor.Addition, error) {\n\treturn nil, errors.New(nil).WithCode(errors.BadRequestCode).\n\t\tWithMessagef(\"addition %s isn't supported\", addition)\n}\n\n// GetArtifactType returns the artifact type\nfunc (m *ManifestProcessor) GetArtifactType(_ context.Context, _ *artifact.Artifact) string {\n\treturn \"\"\n}\n\n// ListAdditionTypes returns the supported addition types\nfunc (m *ManifestProcessor) ListAdditionTypes(_ context.Context, _ *artifact.Artifact) []string {\n\treturn nil\n}\n\n// UnmarshalConfig unmarshal the config blob of the artifact into the specified object \"v\"\nfunc (m *ManifestProcessor) UnmarshalConfig(_ context.Context, repository string, manifest []byte, v any) error {\n\t// unmarshal manifest\n\tmani := &v1.Manifest{}\n\tif err := json.Unmarshal(manifest, mani); err != nil {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/controller/artifact/processor/base/manifest.go#L50-L86","documentation":"base.ManifestProcessor is the shared base for manifest-based processors (chart, CNAI, WASM, SBOM, image v2), all of which override AbstractAddition with their own supported sets. This base implementation is the fallback and rejects any addition with BadRequest when an embedding processor does not override the method — i.e., a manifest-based artifact type with no addition support.","triggerScenarios":"Requesting /artifacts/{ref}/additions/{type} on an artifact handled by a processor that embeds base.ManifestProcessor without overriding AbstractAddition — typically a custom or third-party Harbor processor; all in-tree embedders override it.","commonSituations":"Extending Harbor with a new manifest-based artifact processor and forgetting to implement AbstractAddition; generic addition-probing clients hitting unknown artifact kinds.","solutions":["Do not call the additions endpoint for artifact types whose addition list is empty (ListAdditionTypes returns nothing)","If you develop a custom processor, override AbstractAddition and ListAdditionTypes to declare real support","Check the artifact's reported type/media type in the API response before requesting additions"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func processorSupportsAdditions(mediaType string) bool {\n    // types whose processors override AbstractAddition with a non-empty set\n    switch mediaType {\n    case \"application/vnd.docker.distribution.manifest.v2+json\",\n        \"application/vnd.oci.image.manifest.v1+json\",\n        \"application/vnd.cncf.helm.config.v1+json\",\n        \"application/vnd.wasm.content.layer.v1+wasm\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"add, err := proc.AbstractAddition(ctx, art, addition)\nif err != nil {\n    if errors.IsErr(err, errors.BadRequestCode) && strings.Contains(err.Error(), \"isn't supported\") {\n        // no addition support for this manifest artifact type\n    }\n}","preventionTips":["When writing a custom processor, decide explicitly whether to override AbstractAddition","Surface ListAdditionTypes in client/UI logic and honor empty results","Probe artifact type before calling the additions endpoint"],"tags":["go","harbor","artifact","additions","bad-request","extension"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}