Tencent/WeKnora · error
invalid session_mode: %s
Error message
invalid session_mode: %s
What it means
IMChannel.validateSessionMode enforces that the SessionMode column holds only SessionModeUser or SessionModeThread. BeforeCreate and BeforeSave hooks call it, so persisting a channel with any other value fails at the ORM layer with this message. It is a data-integrity guard against invalid enum values reaching the database.
Source
Thrown at internal/im/types.go:137
// on every save (create + update).
func (ch *IMChannel) BeforeSave(tx *gorm.DB) error {
if ch.SessionMode == "" {
ch.SessionMode = string(SessionModeUser)
}
if err := ch.validateSessionMode(); err != nil {
return err
}
ch.BotIdentity = ch.computeBotIdentity()
return nil
}
// validateSessionMode checks that SessionMode holds a supported value.
func (ch *IMChannel) validateSessionMode() error {
switch SessionMode(ch.SessionMode) {
case SessionModeUser, SessionModeThread:
return nil
default:
return fmt.Errorf("invalid session_mode: %s", ch.SessionMode)
}
}
// computeBotIdentity derives a unique bot identity string from the channel's
// platform, mode, and credentials. Returns "" if no identity can be extracted.
func (ch *IMChannel) computeBotIdentity() string {
creds := make(map[string]interface{})
if err := json.Unmarshal([]byte(ch.Credentials), &creds); err != nil {
return ""
}
str := func(key string) string {
if v, ok := creds[key]; ok {
switch val := v.(type) {
case string:
return val
case float64:
return fmt.Sprintf("%.0f", val)View on GitHub (pinned to 988cbb0330)
Solutions
- Set ch.SessionMode to im.SessionModeUser or im.SessionModeThread before calling Save/Create.
- Query existing rows with invalid session_mode values and migrate them to a valid constant.
- Validate user-supplied session_mode against the two allowed constants at the API boundary before constructing the struct.
Example fix
// before
ch := &im.IMChannel{Platform: "telegram"}
db.Create(ch) // fails: empty SessionMode
// after
ch := &im.IMChannel{Platform: "telegram", SessionMode: string(im.SessionModeThread)}
db.Create(ch) Defensive patterns
Strategy: validation
Validate before calling
func validSessionMode(s string) bool {
return s == string(im.SessionModeUser) || s == string(im.SessionModeThread)
}
if !validSessionMode(ch.SessionMode) {
ch.SessionMode = string(im.SessionModeThread) // or reject
} Type guard
func isSessionMode(s string) bool {
switch im.SessionMode(s) {
case im.SessionModeUser, im.SessionModeThread:
return true
}
return false
} Try / catch
if err := db.Create(ch).Error; err != nil {
if strings.Contains(err.Error(), "invalid session_mode") {
return fmt.Errorf("session_mode %q rejected; allowed: user, thread", ch.SessionMode)
}
return err
} Prevention
- Assign SessionMode only via the im.SessionMode* constants.
- Backfill/migrate legacy rows so every row has a valid enum value.
- Constrain the DB column with a CHECK or enum type as a second guard.
When it happens
Trigger: Saving (BeforeSave) or creating (BeforeCreate) an IMChannel whose SessionMode string is not exactly "user" or "thread" — e.g. an empty string, "User" with wrong casing, or a platform-specific value.
Common situations: Inserting channels directly via SQL or a migration script bypassing hooks earlier and then an update failing; constructing IMChannel structs in tests or seeders without setting SessionMode; renaming enum constants in a refactor without migrating existing rows.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- invalid Metaso search scope: %s
- invite code has expired
- join request not found
- failed to retrieve: %s
- opensearch: index not found
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/cf95d142867c668f.
Report an issue: GitHub.