{"record":{"id":"c689346bcf8d1719","repo":"goharbor/harbor","slug":"missing-parameter-of-scan-job","errorCode":null,"errorMessage":"missing parameter of scan job","messagePattern":"missing parameter of scan job","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/scan/job.go","lineNumber":112,"sourceCode":"func (j *Job) MaxFails() uint {\n\treturn 1\n}\n\n// MaxCurrency is implementation of same method in Interface.\nfunc (j *Job) MaxCurrency() uint {\n\treturn 0\n}\n\n// ShouldRetry indicates if the job should be retried\nfunc (j *Job) ShouldRetry() bool {\n\treturn false\n}\n\n// Validate the parameters of this job\nfunc (j *Job) Validate(params job.Parameters) error {\n\tif params == nil {\n\t\t// Params are required\n\t\treturn errors.New(\"missing parameter of scan job\")\n\t}\n\n\tif _, err := extractRegistration(params); err != nil {\n\t\treturn errors.Wrap(err, \"job validate\")\n\t}\n\n\tif _, err := ExtractScanReq(params); err != nil {\n\t\treturn errors.Wrap(err, \"job validate\")\n\t}\n\n\tif _, err := extractMimeTypes(params); err != nil {\n\t\treturn errors.Wrap(err, \"job validate\")\n\t}\n\n\tif _, err := extractRobotAccount(params); err != nil {\n\t\treturn errors.Wrap(err, \"job validate\")\n\t}\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/scan/job.go#L94-L130","documentation":"Returned by scan Job.Validate when the job parameters map is nil. Scan jobs require at least the registration UUID, the scan request (artifact digest), and mime types; a nil map is rejected before any field extraction is attempted.","triggerScenarios":"Enqueuing a scan job through the jobservice without parameters; API code building job.Job but never setting params; job re-submission after serialization loss of the parameters blob.","commonSituations":"Custom integrations invoking the scan job directly; upgrade migrations dropping old job params; on-demand scan endpoints failing to assemble parameters when the request context is incomplete.","solutions":["Always pass a non-nil job.Parameters containing registration_uuid, the scan request JSON, and mime_types","Validate at the API boundary before enqueuing so users get a 400 instead of a failed job","Inspect the failed job's parameters in the jobservice UI to confirm what was attached"],"exampleFix":"// before\njob := &Job{}\nerr := job.Validate(nil)\n\n// after\nparams := job.Parameters{\n    JobParamRegistration: reg.UUID,\n    JobParameterRequest:  reqJSON,\n    JobParameterMimes:    []string{v1.MimeTypeNativeReport},\n}\nerr := job.Validate(params)","handlingStrategy":"validation","validationCode":"if params == nil {\n    return errors.New(\"scan job requires parameters\")\n}\nif err := job.Validate(params); err != nil {\n    return err\n}","typeGuard":"func hasScanParams(p job.Parameters) bool {\n    return p != nil && p[JobParamRegistration] != nil && p[JobParameterRequest] != nil\n}","tryCatchPattern":null,"preventionTips":["Assemble the full parameters map (registration, request, mime types) before enqueueing","Validate at the API layer so callers get 400s instead of dead jobs","After upgrades, re-test parameter key names; renames break silently"],"tags":["scan","job","parameters","validation"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}