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
- Use one of the supported values: direct, group, or channel (case as expected by the switch).
- Omit chatType and let guessChatType infer it from the chat ID format.
- Log/inspect the actual chatType value received — it is quoted in the error.
- 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
- Define shared string constants for chat types instead of inline literals
- Omit chatType when unsure — it is inferred from the ID format
- Normalize case/whitespace before passing
- Keep a mapping table if porting from another platform's vocabulary
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
- invalid --platform-type %q, want feishu or lark
- unsupported app_type %q (only claude and codex are supported
- invalid platform type %q (want feishu or lark)
- invalid session_mode %q (want reuse, new_per_run, or new-per
- invalid mode %q (want default, bypassPermissions, acceptEdit
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/cdb200ccff1847fb.
Report an issue: GitHub.