{"record":{"id":"e165dbd0a5b3da28","repo":"hashicorp/packer","slug":"addartifacts-failed-to-add-artifact-to-build-q","errorCode":null,"errorMessage":"AddArtifacts: failed to add artifact to build %q: %w","messagePattern":"AddArtifacts: failed to add artifact to build %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/hcp/registry/types.builds.go","lineNumber":89,"sourceCode":"\t\t// TODO: (nywilken) Determine why we skip labels already set\n\t\t// if _, ok := build.Labels[k]; ok {\n\t\t// continue\n\t\t// }\n\t\tbuild.Labels[k] = v\n\t}\n\n}\n\n// AddArtifacts appends one or more artifacts to the build.\nfunc (build *Build) AddArtifacts(artifacts ...packerSDKRegistry.Image) error {\n\n\tif build.Artifacts == nil {\n\t\tbuild.Artifacts = make(map[string]packerSDKRegistry.Image)\n\t}\n\n\tfor _, artifact := range artifacts {\n\t\tif err := artifact.Validate(); err != nil {\n\t\t\treturn fmt.Errorf(\"AddArtifacts: failed to add artifact to build %q: %w\", build.ComponentType, err)\n\t\t}\n\n\t\tif build.Platform == \"\" {\n\t\t\tbuild.Platform = artifact.ProviderName\n\t\t}\n\n\t\tbuild.MergeLabels(artifact.Labels)\n\t\tbuild.Artifacts[artifact.String()] = artifact\n\t}\n\n\treturn nil\n}\n\n// IsNotDone returns true if build does not satisfy all requirements of a completed build.\n// A completed build must have a valid ID, one or more Artifacts, and its Status is HashicorpCloudPacker20230101BuildStatusBUILDDONE.\nfunc (build *Build) IsNotDone() bool {\n\thasBuildID := build.ID != \"\"\n\thasNoArtifacts := len(build.Artifacts) == 0","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/hcp/registry/types.builds.go#L71-L107","documentation":"Returned by Build.AddArtifacts when an artifact fails packerSDKRegistry Image.Validate. Validation requires a usable image identity (non-empty ImageID and ProviderName), so artifacts lacking these cannot be attached to the build.","triggerScenarios":"Any AddArtifacts call where an Image has an empty ImageID (artifact.ExternalIdentifier) or ProviderName; also reached indirectly via NewBuildFromCloudPackerBuild, AddArtifactToBuild, and doCompleteBuild artifact registration.","commonSituations":"Builders that emit artifacts without external identifiers (e.g. docker builder not exporting, or local files); misconfigured post-processors dropping IDs; populating builds from cloud records with blank provider fields.","solutions":["Ensure the builder produces an artifact with a valid external identifier (e.g. an AMI ID, image name)","Verify ImageID and ProviderName are set when constructing packerSDKRegistry.Image values in custom plugins","Inspect the wrapped Validate error (%w) for the exact missing field","Skip registering non-image artifacts rather than forcing them into the HCP registry"],"exampleFix":"// before\nbuild.AddArtifacts(packerSDKRegistry.Image{ImageID: \"\", ProviderName: \"aws\"})\n// after\nif artifact.ExternalIdentifier == \"\" {\n    return fmt.Errorf(\"artifact has no external identifier\")\n}\nbuild.AddArtifacts(packerSDKRegistry.Image{ImageID: artifact.ExternalIdentifier, ProviderName: \"aws\"})","handlingStrategy":"validation","validationCode":"img := packerSDKRegistry.Image{ImageID: artifact.ExternalIdentifier, ProviderName: provider, ProviderRegion: region}\nif err := img.Validate(); err != nil {\n    return fmt.Errorf(\"skip invalid artifact: %w\", err)\n}\nbuild.AddArtifacts(img)","typeGuard":"func validImage(img packerSDKRegistry.Image) bool {\n    return img.ImageID != \"\" && img.ProviderName != \"\"\n}","tryCatchPattern":null,"preventionTips":["Always set ImageID and ProviderName when constructing registry Images","Filter placeholder/empty artifacts before attaching to builds","Test custom builders against Image.Validate in unit tests"],"tags":["hcp-packer","artifact-validation","registry"],"backgroundTag":"artifact-validation-failed","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}