{"record":{"id":"c670f90293c44518","repo":"hashicorp/packer","slug":"write-sbom-q-w","errorCode":null,"errorMessage":"write SBOM %q: %w","messagePattern":"write SBOM %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"post-processor/provenance/post-processor.go","lineNumber":470,"sourceCode":"\t}\n\n\tscanPath, err := p.resolveSBOMScanPath(source)\n\tif err != nil {\n\t\treturn \"\", nil, err\n\t}\n\n\trawSBOM, err := p.generateSBOM(ctx, internalsbom.Config{\n\t\tScanPath: scanPath,\n\t\tFormat:   format,\n\t\tScope:    p.config.SBOMScope,\n\t\tExclude:  append([]string(nil), p.config.SBOMExclude...),\n\t})\n\tif err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"generate SBOM: %w\", err)\n\t}\n\n\tif err := atomicWriteFile(paths.SBOMRaw, rawSBOM, 0664); err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"write SBOM %q: %w\", paths.SBOMRaw, err)\n\t}\n\n\treturn format, rawSBOM, nil\n}\n\nfunc (p *PostProcessor) resolveSBOMScanPath(source packersdk.Artifact) (string, error) {\n\tif p.config.SBOMScanPath != \"\" {\n\t\treturn p.config.SBOMScanPath, nil\n\t}\n\n\tfiles := source.Files()\n\tif len(files) == 1 {\n\t\treturn files[0], nil\n\t}\n\tif len(files) > 1 {\n\t\tparent := filepath.Dir(files[0])\n\t\tfor _, file := range files[1:] {\n\t\t\tif filepath.Dir(file) != parent {","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/post-processor/provenance/post-processor.go#L452-L488","documentation":"Runtime error from resolveSBOM in the provenance post-processor: the generated raw SBOM bytes could not be written to the attestation working directory (atomicWriteFile failed on paths.SBOMRaw) — usually a missing/unwritable directory or disk-full condition.","triggerScenarios":"resolveSBOM (via writeSBOMAttestation) succeeds at generating rawSBOM but atomicWriteFile(paths.SBOMRaw, rawSBOM, 0664) returns an error.","commonSituations":"Output directory for the SBOM artifact doesn't exist; permissions denied for the packer process; disk full; SBOMRaw path collides with a directory or read-only file.","solutions":["Ensure the provenance output directory exists and is writable","Free disk space on the volume holding the build directory"],"exampleFix":"// before\n\"output_path\": \"/mnt/ro/attestation.json\"  # read-only mount\n// after\n\"output_path\": \"./dist/attestation.json\"","handlingStrategy":"try-catch","validationCode":"import os\nfunc ensureWritable(path string) error {\n\tdir := filepath.Dir(path)\n\tif err := os.MkdirAll(dir, 0o755); err != nil { return err }\n\tf, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o664)\n\tif err != nil { return err }\n\treturn f.Close()\n}\n// ensureWritable(expectedSBOMRawPath) before running PostProcess","typeGuard":null,"tryCatchPattern":"if err := p.PostProcess(ctx, a); err != nil {\n\tvar pe *os.PathError\n\tif errors.As(err, &pe) && strings.Contains(err.Error(), \"write SBOM\") {\n\t\tlog.Printf(\"SBOM write failed at %s: %v\", pe.Path, pe.Err)\n\t}\n\treturn err\n}","preventionTips":["Pre-create and chmod the output directory in CI.","Confirm output volume has free space for SBOM payloads.","Avoid pointing output_path at read-only or ephemeral mounts.","Test the provenance post-processor locally before CI rollout."],"tags":["filesystem","sbom","io"],"backgroundTag":"file-write-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"}