chenhg5/cc-connect · warning

dingtalk: card API temporarily degraded

Error message

dingtalk: card API temporarily degraded

What it means

CreateStreamingCard refuses to create a card while the DingTalk card API is marked degraded — an internal circuit-breaker that trips after repeated card API failures so streaming output falls back to plain text instead of hammering a failing API.

Source

Thrown at platform/dingtalk/dingtalk.go:1089

	slog.Info("dingtalk: image message sent", "media_id", mediaID, "user", rc.senderStaffId)
	return nil
}

var _ core.ImageSender = (*Platform)(nil)
var _ core.StreamingCardPlatform = (*Platform)(nil)
var _ core.ReplyContextReconstructor = (*Platform)(nil)
var _ core.TypingIndicator = (*Platform)(nil)
var _ core.TypingIndicatorDone = (*Platform)(nil)

// CreateStreamingCard creates a new streaming card for the given reply context.
// Implements core.StreamingCardPlatform.
func (p *Platform) CreateStreamingCard(ctx context.Context, replyCtx any) (core.StreamingCard, error) {
	if p.cardTemplateID == "" {
		return nil, fmt.Errorf("dingtalk: card_template_id not configured")
	}
	if p.isCardDegraded() {
		return nil, fmt.Errorf("dingtalk: card API temporarily degraded")
	}
	rc, ok := replyCtx.(replyContext)
	if !ok {
		return nil, fmt.Errorf("dingtalk: invalid reply context type %T", replyCtx)
	}
	return p.createAICard(ctx, rc)
}

// SendFile uploads and sends a file via DingTalk oToMessages API.
// Implements core.FileSender.
func (p *Platform) SendFile(ctx context.Context, rctx any, file core.FileAttachment) error {
	rc, ok := rctx.(replyContext)
	if !ok {
		return fmt.Errorf("dingtalk: SendFile: invalid reply context type %T", rctx)
	}

	name := file.FileName
	if name == "" {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Wait for the degradation cooldown to elapse and retry
  2. Fix the underlying card API failures (check earlier logs for createAICard errors)
  3. Verify card-related credentials/permissions in DingTalk open platform
  4. Let the engine fall back to plain-text replies while degraded — this is expected behavior

Example fix

// before
if err := p.SendImage(ctx, rc, img); err != nil { log.Fatal(err) }
// after
if _, err := p.CreateStreamingCard(ctx, rc); err != nil && strings.Contains(err.Error(), "degraded") {
    // platform will fall back to plain text; not fatal
    return
}
Defensive patterns

Strategy: fallback

Try / catch

card, err := p.CreateStreamingCard(ctx, rc)
if err != nil {
    // degraded or otherwise unavailable: fall back to plain text streaming
    card = nil
    slog.Warn("streaming card unavailable, using text fallback", "err", err)
}

Prevention

When it happens

Trigger: Prior createAICard/stream/doStream calls failed repeatedly (token errors, 4xx/5xx from card API), tripping the degradation flag; error self-clears after the cooldown.

Common situations: DingTalk card service outage or sustained 429s; misconfigured card credentials causing every create to fail until the breaker opens.

Related errors


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