chenhg5/cc-connect · error

webex: post chunk %d/%d: %w

Error message

webex: post chunk %d/%d: %w

What it means

This error wraps a failure from the Webex REST API when the platform adapter posts one chunk of a multi-chunk reply. Long replies are split by chunkMarkdown into pieces that fit Webex's message size limit, and each chunk is posted sequentially with PostMessage; the index (i+1/len) identifies which chunk failed. The wrapped error from p.client.PostMessage carries the underlying API/network cause.

Source

Thrown at platform/webex/webex_reply.go:51

// Send posts a non-threaded (proactive) message to the room.
func (p *Platform) Send(ctx context.Context, replyCtx any, content string) error {
	rc, err := asReplyContext(replyCtx)
	if err != nil {
		return err
	}
	return p.post(ctx, rc.roomID, "", content)
}

// post chunks content and posts each chunk; only the first chunk threads.
func (p *Platform) post(ctx context.Context, roomID, parentID, content string) error {
	chunks := chunkMarkdown(content, webexMaxBytes)
	for i, chunk := range chunks {
		pid := ""
		if i == 0 {
			pid = parentID
		}
		if err := p.client.PostMessage(ctx, roomID, pid, chunk); err != nil {
			return fmt.Errorf("webex: post chunk %d/%d: %w", i+1, len(chunks), err)
		}
	}
	return nil
}

// chunkMarkdown splits text to fit within limit bytes, preferring paragraph
// (\n\n), then line (\n), then a hard cut.
func chunkMarkdown(text string, limit int) []string {
	if len(text) <= limit {
		return []string{text}
	}
	var out []string
	rest := text
	for len(rest) > limit {
		cut := strings.LastIndex(rest[:limit], "\n\n")
		if cut <= 0 {
			cut = strings.LastIndex(rest[:limit], "\n")
		}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Inspect the wrapped cause (%w) to see the Webex API error code; fix auth or room access accordingly.
  2. Refresh/renew the bot access token if the error indicates 401/invalid token.
  3. Verify the bot is still a member of the target roomID; re-invite if removed.
  4. Implement retry with backoff on the failed chunk (earlier chunks already posted; consider idempotent re-send handling).
  5. Reduce message size or chunk count to lower the chance of hitting rate limits.

Example fix

// before
if err := p.client.PostMessage(ctx, roomID, pid, chunk); err != nil {
	return fmt.Errorf("webex: post chunk %d/%d: %w", i+1, len(chunks), err)
}
// after
if err := p.client.PostMessage(ctx, roomID, pid, chunk); err != nil {
	if isRateLimited(err) {
		time.Sleep(backoff(i))
		if retryErr := p.client.PostMessage(ctx, roomID, pid, chunk); retryErr != nil {
			return fmt.Errorf("webex: post chunk %d/%d (after retry): %w", i+1, len(chunks), retryErr)
		}
		continue
	}
	return fmt.Errorf("webex: post chunk %d/%d: %w", i+1, len(chunks), err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if len(text) == 0 { return errors.New("empty reply text") } // and check roomID non-empty before calling Send/Reply

Type guard

null

Try / catch

err := platform.Send(ctx, roomID, text)
if err != nil {
	var apiErr *APIError
	if errors.As(err, &apiErr) && apiErr.Code == 401 { refreshToken() }
	return err
}

Prevention

When it happens

Trigger: Reply or Send is called with text long enough to be split into chunks, and PostMessage fails for a non-first chunk — e.g. HTTP 4xx/5xx from Webex (expired token, room deleted, rate limit) or a network failure mid-loop.

Common situations: Bot access token expired or revoked mid-conversation; bot removed from the room after the first chunk posted; Webex rate limiting on rapid long replies; transient network outage during a long multi-chunk message.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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