chenhg5/cc-connect · error

dingtalk: proactive send requires conversationId (group) or

Error message

dingtalk: proactive send requires conversationId (group) or senderStaffId (direct)

What it means

The DingTalk platform adapter refuses to send a proactive (unsolicited) message when the request lacks a target. A proactive send to a group needs the group's conversationId (openConversationId), while a direct send to a user needs the senderStaffId used to batch-send via userIds. The adapter builds the request payload only when one of these identifiers is present; otherwise it fails fast instead of calling the API with an empty target.

Source

Thrown at platform/dingtalk/dingtalk.go:1675

		msgParam, _ := json.Marshal(map[string]string{"text": content})
		requestBody = map[string]any{
			"robotCode":          p.robotCode,
			"openConversationId": rc.conversationId,
			"msgKey":             "sampleMarkdown",
			"msgParam":           string(msgParam),
		}
	} else if rc.senderStaffId != "" {
		// Direct message via /v1.0/robot/oToMessages/batchSend
		apiURL = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend"
		msgParam, _ := json.Marshal(map[string]string{"title": cardTitleFromContent(content), "text": content})
		requestBody = map[string]any{
			"robotCode": p.robotCode,
			"userIds":   []string{rc.senderStaffId},
			"msgKey":    "sampleMarkdown",
			"msgParam":  string(msgParam),
		}
	} else {
		return fmt.Errorf("dingtalk: proactive send requires conversationId (group) or senderStaffId (direct)")
	}

	body, err := json.Marshal(requestBody)
	if err != nil {
		return fmt.Errorf("dingtalk: marshal proactive message: %w", err)
	}

	req, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(body))
	if err != nil {
		return fmt.Errorf("dingtalk: create proactive request: %w", err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("x-acs-dingtalk-access-token", token)

	resp, err := p.httpClient.Do(req)
	if err != nil {
		return fmt.Errorf("dingtalk: proactive send request: %w", err)
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Set the target identifier: pass the group conversationId (openConversationId) for group sends, or the user's senderStaffId/staffId for direct sends, in the message context or options used for the proactive send.
  2. For scheduled sends, persist the conversationId (or staffId) from the first inbound interaction and reuse it when triggering the proactive message.
  3. If the message is a reply to an inbound message, use the normal reply path (Reply) instead of the proactive send path so the target is inherited automatically.

Example fix

// before
rc := core.RequestContext{} // no conversationId, no senderStaffId
p.Send(ctx, rc, "daily report")
// after
rc := core.RequestContext{ConversationID: "cidXXXXXXXX"} // from stored chat binding
p.Send(ctx, rc, "daily report")
Defensive patterns

Strategy: validation

Validate before calling

func canProactiveSend(rc RequestContext) error {
    if rc.ConversationID == "" && rc.SenderStaffID == "" {
        return errors.New("dingtalk: need conversationId or senderStaffId for proactive send")
    }
    return nil
}

Prevention

When it happens

Trigger: Calling the platform's proactive send path (e.g. Send outside of an inbound-message reply context) where neither rc.conversationId (group) nor rc.senderStaffId (direct) was populated — for example a cron/timer notification with no chat context attached.

Common situations: Scheduled/timed messages built without a stored conversationId; forwarding an agent response through a session whose originating message metadata was dropped; config missing the chat binding for proactive notifications.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/397dd92c59f5a305. Report an issue: GitHub.