{"record":{"id":"c892d08bf041a114","repo":"crowdsecurity/crowdsec","slug":"message-for-s-contains-bad-alert-format-w","errorCode":null,"errorMessage":"message for '%s' contains bad alert format: %w","messagePattern":"message for '(.+?)' contains bad alert format: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiserver/papi_cmd.go","lineNumber":101,"sourceCode":"\tdefault:\n\t\treturn fmt.Errorf(\"unknown command '%s' for operation type '%s'\", message.Header.OperationCmd, message.Header.OperationType)\n\t}\n\n\treturn nil\n}\n\nfunc AlertCmd(ctx context.Context, message *Message, p *Papi, sync bool) error {\n\tswitch message.Header.OperationCmd {\n\tcase \"add\":\n\t\tdata, err := json.Marshal(message.Data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\talert := &models.Alert{}\n\n\t\tif err := json.Unmarshal(data, alert); err != nil {\n\t\t\treturn fmt.Errorf(\"message for '%s' contains bad alert format: %w\", message.Header.OperationType, err)\n\t\t}\n\n\t\tlog.Infof(\"Received order %s from PAPI (%d decisions)\", alert.UUID, len(alert.Decisions))\n\t\tdecisionsToKeep := make([]*models.Decision, 0)\n\t\tfor _, decision := range alert.Decisions {\n\t\t\tif decision.Value == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tisAllowlisted, reason, err := p.DBClient.IsAllowlisted(ctx, *decision.Value)\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"Failed to check if decision '%s' is allowlisted: %s\", *decision.Value, err)\n\t\t\t\t// keep the decision in case of error during allowlist check\n\t\t\t\tdecisionsToKeep = append(decisionsToKeep, decision)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif isAllowlisted {\n\t\t\t\tlog.Infof(\"Decision '%s' is allowlisted, removing it (%s)\", *decision.Value, reason)\n\t\t\t\tcontinue","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/papi_cmd.go#L83-L119","documentation":"A PAPI (console) message carrying an alert 'add' command had a Data field that could not be unmarshalled into models.Alert after a round-trip through json.Marshal. The message header/operation was valid; the payload body does not match the Alert schema expected by this crowdsec version.","triggerScenarios":"json.Unmarshal(data, alert) fails on an alert message: schema drift between sender and consumer, malformed JSON, or wrong field types.","commonSituations":"CAPI/PAPI server newer than the local crowdsec sending extended Alert structures, intercepted/corrupted message payload, custom sender producing non-standard alerts.","solutions":["Update crowdsec so models.Alert matches the server's schema","Capture and inspect the raw payload to spot the schema difference","Verify the sender is an official crowdsec component"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"var probe map[string]any; if err := json.Unmarshal(data, &probe); err != nil { return err }; if _, ok := probe[\"decisions\"]; !ok { return fmt.Errorf(\"alert payload missing decisions\") }","typeGuard":"func isAlertShape(m map[string]any) bool { _, hasUUID := m[\"uuid\"]; _, hasDecisions := m[\"decisions\"]; return hasUUID && hasDecisions }","tryCatchPattern":"if err := AlertCmd(ctx, msg, p, false); err != nil { if strings.Contains(err.Error(), \"bad alert format\") { log.Errorf(\"invalid alert from PAPI: %v\", err) } }","preventionTips":["Sync models.Alert with server schema on upgrades","Validate decision fields (non-nil Value) before processing","Log raw payloads when schema drift is suspected"],"tags":["json","papi","alert"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}