chenhg5/cc-connect · error

tuitui: invalid chat type %q

Error message

tuitui: invalid chat type %q

What it means

FetchHistory was called with a chatType other than the supported "direct", "group", or "channel". TuiTui dispatches history fetching to different endpoints per chat type; any unrecognized type is rejected. Note that an empty chatType is auto-guessed from the ID format, so this error only fires for explicitly wrong non-empty values.

Source

Thrown at platform/tuitui/history.go:45

	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
	} else {
		payload["group_id"] = chatID
	}
	addHistoryOptions(payload, opts)

	apiPath := "/robot/message/group/sync"
	if chatType == chatTypeDirect {
		apiPath = "/robot/message/single/sync"
	}
	var out struct {
		ErrCode int              `json:"errcode"`

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Use one of the supported values: direct, group, or channel (case as expected by the switch).
  2. Omit chatType and let guessChatType infer it from the chat ID format.
  3. Log/inspect the actual chatType value received — it is quoted in the error.
  4. Normalize input with strings.ToLower(strings.TrimSpace(chatType)) before calling.

Example fix

// before
p.FetchHistory(ctx, chatID, "private", opts)
// after
p.FetchHistory(ctx, chatID, "direct", opts) // or "" to auto-guess
Defensive patterns

Strategy: validation

Validate before calling

var validChatTypes = map[string]bool{"direct": true, "group": true, "channel": true}
if !validChatTypes[strings.ToLower(strings.TrimSpace(chatType))] {
    chatType = "" // let guessChatType infer
}

Type guard

func isKnownChatType(t string) bool {
    switch strings.ToLower(strings.TrimSpace(t)) {
    case "direct", "group", "channel": return true
    }
    return false
}

Try / catch

res, err := p.FetchHistory(ctx, chatID, chatType, opts)
if err != nil {
    var inv *invalidChatTypeError
    if errors.As(err, &inv) { chatType = ""; res, err = p.FetchHistory(ctx, chatID, "", opts) }
}

Prevention

When it happens

Trigger: Calling FetchHistory(ctx, id, "chat", opts) or any misspelled type; passing a type constant from another platform (e.g. "private", "dm", "channel_post"); user-configured chat type with a typo.

Common situations: Copied code from another platform adapter using its chat-type vocabulary; config file mapping chats with the wrong type labels; refactor renamed constants but a call site was missed.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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