chenhg5/cc-connect · error

tuitui: chat id is required

Error message

tuitui: chat id is required

What it means

TuiTui's FetchHistory was called with an empty chatID. The platform cannot construct any history API request without knowing which chat to fetch, so it rejects the call upfront. This is a caller-contract violation, not a network failure.

Source

Thrown at platform/tuitui/history.go:34

	Limit        int    `json:"limit,omitempty"`
	OrderAsc     *bool  `json:"order_asc,omitempty"`
}

type HistoryResult struct {
	ErrCode     int              `json:"errcode"`
	ErrMsg      string           `json:"errmsg,omitempty"`
	Cursor      string           `json:"cursor,omitempty"`
	HasMore     bool             `json:"has_more,omitempty"`
	CurrentTime any              `json:"current_time,omitempty"`
	Subject     string           `json:"subject,omitempty"`
	Messages    []map[string]any `json:"msgs,omitempty"`
	Threads     []string         `json:"threads,omitempty"`
}

func (p *Platform) FetchHistory(ctx context.Context, chatID, chatType string, opts HistoryOptions) (*HistoryResult, error) {
	chatID = strings.TrimSpace(chatID)
	if chatID == "" {
		return nil, fmt.Errorf("tuitui: chat id is required")
	}
	if chatType == "" {
		chatType = guessChatType(chatID)
	}
	switch chatType {
	case chatTypeDirect, chatTypeGroup:
		return p.fetchDirectOrGroupHistory(ctx, chatID, chatType, opts)
	case chatTypeChannel:
		return p.fetchChannelHistory(ctx, chatID, opts)
	default:
		return nil, fmt.Errorf("tuitui: invalid chat type %q", chatType)
	}
}

func (p *Platform) fetchDirectOrGroupHistory(ctx context.Context, chatID, chatType string, opts HistoryOptions) (*HistoryResult, error) {
	payload := map[string]any{"cursor": "0"}
	if chatType == chatTypeDirect {
		payload["user"] = chatID

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Ensure the caller extracts chatID from the incoming message/event before calling FetchHistory.
  2. Guard the call site: skip history fetch when chatID is empty.
  3. Trim user-supplied IDs and validate non-empty before passing.
  4. If the ID comes from config or a DB lookup, check that the lookup succeeded.

Example fix

// before
result, err := p.FetchHistory(ctx, chatID, "group", opts)
// after
if strings.TrimSpace(chatID) == "" {
    return nil, fmt.Errorf("cannot fetch history: chatID is empty")
}
result, err := p.FetchHistory(ctx, chatID, "group", opts)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(chatID) == "" {
    return fmt.Errorf("skip: chatID empty")
}

Type guard

func hasChatID(m core.Message) bool { return strings.TrimSpace(m.ChatID) != "" }

Try / catch

res, err := p.FetchHistory(ctx, chatID, chatType, opts)
if err != nil && strings.Contains(err.Error(), "chat id is required") {
    slog.Warn("no chat id available; skipping history fetch")
    return
}

Prevention

When it happens

Trigger: Calling FetchHistory(ctx, "", chatType, opts) directly, or routing a message whose chat ID was not extracted (e.g. webhook payload missing the chat identifier, or chatID that trims to whitespace).

Common situations: Integration code passing an uninitialized variable as chat ID; a message from an unsupported event type lacking a chat identifier forwarded to FetchHistory; test harness forgetting to set the chat ID field.

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/5e0a12a3715c2556. Report an issue: GitHub.