{"record":{"id":"ade91abd2f11daf8","repo":"multica-ai/multica","slug":"dingtalk-user-id-is-already-bound-to-a-different","errorCode":null,"errorMessage":"dingtalk: user id is already bound to a different user","messagePattern":"dingtalk: user id is already bound to a different user","errorType":"http","errorClass":"ErrBindingAlreadyAssigned","httpStatus":409,"severity":"error","filePath":"server/internal/integrations/dingtalk/binding.go","lineNumber":37,"sourceCode":"\n// This file is the DingTalk user-binding token flow: an unbound DingTalk user\n// who messages the bot gets a \"link your account\" prompt (minted here, delivered\n// by the OutboundReplier), clicks through to the in-product redeem page, and\n// their DingTalk staff id is bound to their Multica account. It mirrors\n// slack.BindingTokenService but runs on the generic channel_* queries with\n// channel_type='dingtalk'.\n\n// BindingTokenTTL bounds a token's life. The channel_binding_token CHECK\n// enforces the same 15-minute cap so a misconfigured caller cannot mint longer.\nconst BindingTokenTTL = 15 * time.Minute\n\nvar (\n\t// ErrBindingTokenInvalid: token unknown / already consumed / expired. One\n\t// opaque error for all three avoids a replay timing oracle.\n\tErrBindingTokenInvalid = errors.New(\"dingtalk: binding token invalid or expired\")\n\t// ErrBindingAlreadyAssigned: this DingTalk user id is already bound to a\n\t// different Multica user (account transfer must go through explicit unbind).\n\tErrBindingAlreadyAssigned = errors.New(\"dingtalk: user id is already bound to a different user\")\n\t// ErrBindingNotWorkspaceMember: the redeemer is not a member of the token's\n\t// workspace. Translated to 403 at the HTTP boundary.\n\tErrBindingNotWorkspaceMember = errors.New(\"dingtalk: redeemer is not a workspace member\")\n)\n\n// BindingToken is a freshly minted token. The raw value is returned exactly\n// once (embedded in the binding URL); only its hash is persisted.\ntype BindingToken struct {\n\tRaw       string\n\tExpiresAt time.Time\n}\n\n// RedeemedBindingToken is returned after a successful redemption.\ntype RedeemedBindingToken struct {\n\tWorkspaceID    pgtype.UUID\n\tInstallationID pgtype.UUID\n\tDingTalkUserID string\n}","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/integrations/dingtalk/binding.go#L19-L55","documentation":"Error \"dingtalk: user id is already bound to a different user\" thrown in multica-ai/multica.","triggerScenarios":"Thrown at server/internal/integrations/dingtalk/binding.go:37 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Unbind the DingTalk user id from the other account first, or sign in as that account."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}