{"record":{"id":"f0645428a0cfd213","repo":"chenhg5/cc-connect","slug":"marshal-payload-w","errorCode":null,"errorMessage":"marshal payload: %w","messagePattern":"marshal payload: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"platform/dingtalk/card.go","lineNumber":111,"sourceCode":"\t\t\"openSpaceId\":           openSpaceId,\n\t\t\"userIdType\":            1,\n\t}\n\n\t// Set delivery model based on conversation type\n\tif isGroup {\n\t\tpayload[\"imGroupOpenDeliverModel\"] = map[string]any{\n\t\t\t\"robotCode\": p.robotCode,\n\t\t}\n\t} else {\n\t\tpayload[\"imRobotOpenDeliverModel\"] = map[string]any{\n\t\t\t\"spaceType\": \"IM_ROBOT\",\n\t\t\t\"robotCode\": p.robotCode,\n\t\t}\n\t}\n\n\tbodyBytes, err := json.Marshal(payload)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"marshal payload: %w\", err)\n\t}\n\n\treqCtx, cancel := context.WithTimeout(ctx, 30*time.Second)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(reqCtx, http.MethodPost,\n\t\t\"https://api.dingtalk.com/v1.0/card/instances/createAndDeliver\",\n\t\tbytes.NewReader(bodyBytes))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"create request: %w\", err)\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"x-acs-dingtalk-access-token\", token)\n\n\tslog.Debug(\"dingtalk: creating AI card\", \"outTrackId\", outTrackId, \"isGroup\", isGroup)\n\n\tresp, err := p.httpClient.Do(req)","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/card.go#L93-L129","documentation":"This error wraps a failure from json.Marshal when serializing the createAndDeliver request payload in platform/dingtalk/card.go:111 (createAICard, called by CreateStreamingCard). The payload is a map[string]any of card template ID, outTrackId, cardData, and delivery models, all strings/numbers, so marshal failure is nearly impossible in practice and indicates an internal invariant violation (e.g. an unsupported value type such as a channel or func injected into the payload).","triggerScenarios":"json.Marshal returns an error while serializing the createAndDeliver payload map; this only happens if a value in the payload map is of a type json cannot encode (func, chan, or a type with a failing MarshalJSON method).","commonSituations":"Custom builds where cardTemplateID, robotCode, or cardData values were replaced with unsupported custom types (e.g. a wrapper type with a panicking/failing MarshalJSON); practically never seen with stock string/number config values.","solutions":["Inspect the payload values passed to createAICard; log fmt.Sprintf(\"%T\", v) for each payload entry to find the non-serializable value","Ensure cardTemplateID, robotCode, conversationId, and senderStaffId are plain strings from config, not custom types with failing MarshalJSON","Since all stock values are JSON-safe, treat this as a bug and report it with the wrapped %w error chain"],"exampleFix":"// before (custom type breaks marshal)\ntype templateID struct{ ID string }\nfunc (t templateID) MarshalJSON() ([]byte, error) { return nil, errors.New(\"unsupported\") }\n// after\nvar cardTemplateID string = \"your-template-id\"","handlingStrategy":"validation","validationCode":"if b, err := json.Marshal(payload); err != nil {\n\treturn fmt.Errorf(\"dingtalk payload not serializable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := createCard(ctx, rc); err != nil {\n\tvar marshalErr error\n\tif errors.Unwrap(err) != nil && strings.Contains(err.Error(), \"marshal payload\") {\n\t\tmarshalErr = err\n\t\tlog.Printf(\"payload serialization bug: %v\", marshalErr)\n\t}\n}","preventionTips":["Keep payload values as plain strings, numbers, and booleans","Never put func/chan/interface{}-holding-runtime values into API payload maps","Add a one-time startup self-test that marshals a representative payload"],"tags":["go","json","serialization","dingtalk"],"backgroundTag":"json-marshal-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}