{"record":{"id":"0d292ec60466f6fd","repo":"hashicorp/packer","slug":"unsupported-scope-s","errorCode":null,"errorMessage":"unsupported scope: %s","messagePattern":"unsupported scope: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sbom/generator_syft.go","lineNumber":44,"sourceCode":"\tgetSourceCfg := syft.DefaultGetSourceConfig()\n\tif len(g.config.Exclude) > 0 {\n\t\tgetSourceCfg = getSourceCfg.WithExcludeConfig(source.ExcludeConfig{Paths: g.config.Exclude})\n\t}\n\n\tsrc, err := syft.GetSource(ctx, sourceInput, getSourceCfg)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get source: %w\", err)\n\t}\n\tdefer func() { _ = src.Close() }()\n\n\tvar scope source.Scope\n\tswitch g.config.Scope {\n\tcase ScopeAllLayers:\n\t\tscope = source.AllLayersScope\n\tcase \"\", ScopeSquashed:\n\t\tscope = source.SquashedScope\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported scope: %s\", g.config.Scope)\n\t}\n\n\tsbomCfg := syft.DefaultCreateSBOMConfig().\n\t\tWithSearchConfig(cataloging.SearchConfig{\n\t\t\tScope: scope,\n\t\t}).\n\t\tWithParallelism(g.config.Parallelism)\n\n\tsbomResult, err := syft.CreateSBOM(ctx, src, sbomCfg)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create SBOM: %w\", err)\n\t}\n\n\treturn g.encodeToFormat(sbomResult)\n}\n\n// encodeToFormat encodes the SBOM to the requested format.\nfunc (g *Generator) encodeToFormat(sbomData *sbom.SBOM) ([]byte, error) {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/sbom/generator_syft.go#L26-L62","documentation":"Inside Generate, g.config.Scope is mapped to a source.Scope; only 'all-layers', '' and 'squashed' are recognized. Any other value returns `unsupported scope: %s`. Normally unreachable because ParseScopeFromArgs and NewGenerator normalize scope, but code that populates Config directly can insert invalid values.","triggerScenarios":"Constructing sbom.Config{Scope: \"directory\"} or another raw string and calling Generate without passing it through ParseScopeFromArgs/NewGenerator; config sources bypassing validation (HCL field set to an arbitrary value).","commonSituations":"Users setting scope via template fields with values like \"all-layers:\" or \"squashed+uncompressed\" copied from other tools; programmatic callers of the internal package skipping ParseScopeFromArgs.","solutions":["Set Scope only via ParseScopeFromArgs, or leave it empty so NewGenerator defaults to squashed","Accept only \"squashed\" or \"all-layers\" in the HCL/template config surface and validate early","Update any stored config that holds a non-canonical scope string"],"exampleFix":"// before\ngen := sbom.NewGenerator(sbom.Config{Scope: scopeFromUser}) // raw, unvalidated\n// after\nscope, err := sbom.ParseScopeFromArgs(scopeFromUser)\nif err != nil { return err }\ngen := sbom.NewGenerator(sbom.Config{Scope: scope})","handlingStrategy":"validation","validationCode":"scope, err := sbom.ParseScopeFromArgs(cfg.Scope)\nif err != nil { return err }\ncfg.Scope = scope\ngen := sbom.NewGenerator(cfg)","typeGuard":"func validScope(s string) bool { return s == \"\" || s == \"squashed\" || s == \"all-layers\" }","tryCatchPattern":"out, err := gen.Generate(ctx)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"unsupported scope\") { return fmt.Errorf(\"fix Scope in config: %w\", err) }\n    return err\n}","preventionTips":["Never assign raw user strings to Config.Scope without ParseScopeFromArgs","Centralize scope parsing at config load","Constrain template fields for scope to known values"],"tags":["go","validation","config","syft","sbom"],"backgroundTag":"unsupported-scope","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"}