{"record":{"id":"d3be6e217e0adf9d","repo":"goharbor/harbor","slug":"10013-d3be6e","errorCode":"10013","errorMessage":"missing parameter of slack job","messagePattern":"missing parameter of slack job","errorType":"validation","errorClass":"badRequestError","httpStatus":400,"severity":"error","filePath":"src/jobservice/job/impl/notification/slack_job.go","lineNumber":66,"sourceCode":"\t}\n\treturn result\n}\n\n// MaxCurrency is implementation of same method in Interface.\nfunc (sj *SlackJob) MaxCurrency() uint {\n\treturn 1\n}\n\n// ShouldRetry ...\nfunc (sj *SlackJob) ShouldRetry() bool {\n\treturn true\n}\n\n// Validate implements the interface in job/Interface\nfunc (sj *SlackJob) Validate(params job.Parameters) error {\n\tif params == nil {\n\t\t// Params are required\n\t\treturn errors.New(\"missing parameter of slack job\")\n\t}\n\n\tpayload, ok := params[\"payload\"]\n\tif !ok {\n\t\treturn errors.Errorf(\"missing job parameter 'payload'\")\n\t}\n\t_, ok = payload.(string)\n\tif !ok {\n\t\treturn errors.Errorf(\"malformed job parameter 'payload', expecting string but got %s\", reflect.TypeOf(payload).String())\n\t}\n\n\taddress, ok := params[\"address\"]\n\tif !ok {\n\t\treturn errors.Errorf(\"missing job parameter 'address'\")\n\t}\n\t_, ok = address.(string)\n\tif !ok {\n\t\treturn errors.Errorf(\"malformed job parameter 'address', expecting string but got %s\", reflect.TypeOf(address).String())","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/jobservice/job/impl/notification/slack_job.go#L48-L84","documentation":"The Slack notification job's Validate (src/jobservice/job/impl/notification/slack_job.go:66) rejects a nil params map with code 10013. Subsequent checks require string entries 'payload' (the Slack message body) and 'address' (the webhook URL); this specific message means the whole params map was absent, not merely one field.","triggerScenarios":"A Slack webhook policy firing with no params constructed — e.g. a custom notification handler or replayed event that failed to build payload/address; direct job submission with params null.","commonSituations":"Webhook policy misconfiguration; Harbor upgrades changing how the notification payload builder assembles params; testing the notification job with empty parameters.","solutions":["Ensure the notification flow constructs params with 'payload' (string) and 'address' (string webhook URL)","Check the Slack webhook policy target settings in the project configuration","Re-trigger the notification after fixing the payload builder"],"exampleFix":"// before\nparams := job.Parameters(nil)\n// after\nparams := job.Parameters{\n    \"payload\":  \"registry notification: artifact pushed\",\n    \"address\": \"https://hooks.slack.com/services/T000/B000/XXXX\",\n}","handlingStrategy":"validation","validationCode":"if params == nil {\n    return fmt.Errorf(\"slack job requires params\")\n}\nfor _, k := range []string{\"payload\", \"address\"} {\n    if _, ok := params[k].(string); !ok {\n        return fmt.Errorf(\"slack job requires string param %q\", k)\n    }\n}","typeGuard":"func isSlackParamsValid(params job.Parameters) bool {\n    p, ok1 := params[\"payload\"].(string)\n    a, ok2 := params[\"address\"].(string)\n    return ok1 && ok2 && p != \"\" && a != \"\"\n}","tryCatchPattern":null,"preventionTips":["Build Slack params (payload + address) in one helper used by every notification path","Type-assert params as strings before submitting — the job rejects non-strings","Test the webhook policy end-to-end after Harbor upgrades"],"tags":["jobservice","notification","slack","webhook","validation","harbor"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}