{"record":{"id":"34fdf2d82f1ea092","repo":"chenhg5/cc-connect","slug":"dingtalk-invalid-conversation-type-q-in-session","errorCode":null,"errorMessage":"dingtalk: invalid conversation type %q in session key: %q","messagePattern":"dingtalk: invalid conversation type %q in session key: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/dingtalk/dingtalk.go","lineNumber":1619,"sourceCode":"\n// ReconstructReplyCtx implements core.ReplyContextReconstructor.\n// Session key format: \"dingtalk:{convType}:{conversationId}:{senderStaffId}\" or \"dingtalk:{convType}:{conversationId}\"\n// where convType is \"g\" (group) or \"d\" (direct/1:1).\nfunc (p *Platform) ReconstructReplyCtx(sessionKey string) (any, error) {\n\tif !strings.HasPrefix(sessionKey, \"dingtalk:\") {\n\t\treturn nil, fmt.Errorf(\"dingtalk: not a dingtalk session key: %q\", sessionKey)\n\t}\n\n\tstripped := strings.TrimPrefix(sessionKey, \"dingtalk:\")\n\tparts := strings.SplitN(stripped, \":\", 3)\n\n\tif len(parts) < 2 {\n\t\treturn nil, fmt.Errorf(\"dingtalk: invalid session key format: %q\", sessionKey)\n\t}\n\n\tconvType := parts[0]\n\tif convType != \"g\" && convType != \"d\" {\n\t\treturn nil, fmt.Errorf(\"dingtalk: invalid conversation type %q in session key: %q\", convType, sessionKey)\n\t}\n\n\tconversationId := parts[1]\n\tif conversationId == \"\" {\n\t\treturn nil, fmt.Errorf(\"dingtalk: empty conversationId in session key: %q\", sessionKey)\n\t}\n\n\tvar senderStaffId string\n\tif len(parts) > 2 {\n\t\tsenderStaffId = parts[2]\n\t}\n\n\treturn replyContext{\n\t\tconversationId: conversationId,\n\t\tsenderStaffId:  senderStaffId,\n\t\tisGroup:        convType == \"g\",\n\t\tproactive:      true,\n\t}, nil","sourceCodeStart":1601,"sourceCodeEnd":1637,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/dingtalk.go#L1601-L1637","documentation":"The session key parsed into enough segments, but the conversation type segment is neither 'g' (group) nor 'd' (direct/1:1) — the only two convTypes the DingTalk adapter emits. The key is not one this platform produced, so reconstruction is refused.","triggerScenarios":"A session key like 'dingtalk:x:cid123' where the convType slot holds an arbitrary string; keys from a different adapter version that used different convType letters; typos in hand-constructed keys.","commonSituations":"Hand-building keys after reading an outdated doc or code sample; mixing keys from a forked/modified adapter; automated migrations writing placeholder convTypes.","solutions":["Use only 'g' for group conversations or 'd' for direct 1:1 conversations in the second segment.","Check adapter version history — if keys were generated by an older/newer version, migrate them to the g/d scheme.","Re-capture the key from a real incoming message (the adapter builds it as dingtalk:g:<cid> or dingtalk:d:<cid>:<staffId>).","Grep your persistence layer for dingtalk:* keys whose second segment is not g/d and fix or drop them."],"exampleFix":"// before\nsessionKey := \"dingtalk:group:cid123\" // wrong convType\nrc, err := platform.ReconstructReplyCtx(sessionKey)\n// after\nsessionKey := \"dingtalk:g:cid123\" // 'g' = group, 'd' = direct\nrc, err := platform.ReconstructReplyCtx(sessionKey)","handlingStrategy":"validation","validationCode":"func hasValidConvType(key string) bool {\n    rest := strings.TrimPrefix(key, \"dingtalk:\")\n    parts := strings.SplitN(rest, \":\", 3)\n    return len(parts) >= 1 && (parts[0] == \"g\" || parts[0] == \"d\")\n}\n// guard before reconstruction\nif !hasValidConvType(sessionKey) {\n    return fmt.Errorf(\"convType must be 'g' or 'd'\")\n}","typeGuard":"func isKnownConvType(t string) bool {\n    return t == \"g\" || t == \"d\"\n}","tryCatchPattern":"ctx, err := platform.ReconstructReplyCtx(sessionKey)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid conversation type\") {\n        slog.Error(\"unknown convType in dingtalk key; regenerate from live message\", \"key\", sessionKey)\n        return errBadConvType\n    }\n    return err\n}","preventionTips":["Only use 'g' (group) and 'd' (direct) when constructing keys.","After upgrading the adapter, migrate old keys whose convType letters differ.","Copy keys from adapter output/logs verbatim, never retype them.","Add a regex check ^dingtalk:[gd]: to key-validating scripts."],"tags":["session-key","enum","validation","dingtalk"],"backgroundTag":"invalid-enum-value","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"}