Fix AttributeError when memories disabled and setting is None (#1296)

## Summary
- Add null checks for `config.setting` in `get_chat_model()` and
`aget_chat_model()` to prevent `AttributeError` when memories are
disabled
- When the memory toggle creates a `UserConversationConfig` via
`get_or_create` with `setting=None`, accessing
`config.setting.price_tier` crashes — now falls through to the default
chat model instead

## Root Cause
The "Enable Memories" toggle PATCH endpoint uses `get_or_create` on
`UserConversationConfig`, which can create a config with `setting=None`.
Both `get_chat_model()` and `aget_chat_model()` then crash:
- For subscribed users: `if config:` passes but `return config.setting`
returns `None`, causing downstream crashes
- For non-subscribed users: `config.setting.price_tier` raises
`AttributeError` on `None`

## Fix
Change `if config:` → `if config and config.setting:` (subscribed path)
and add `and config.setting` guard before `.price_tier` access
(non-subscribed path), in both sync and async variants.

## Test plan
- [ ] Toggle memories off with no prior chat model configured — settings
page should still load
- [ ] Chat responses should use default model when setting is None
- [ ] Existing users with configured chat models should be unaffected

Fixes #1287

Signed-off-by: majiayu000 <1835304752@qq.com>
This commit is contained in:
lif 2026-03-26 10:56:25 +08:00 committed by GitHub
parent 7475a781bc
commit 8b8504edb8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1192,13 +1192,13 @@ class ConversationAdapters:
config = UserConversationConfig.objects.filter(user=user).first()
if subscribed:
# Subscibed users can use any available chat model
if config:
if config and config.setting:
return config.setting
# Fallback to the default advanced chat model
return ConversationAdapters.get_advanced_chat_model(user)
else:
# Non-subscribed users can use any free chat model
if config and config.setting.price_tier == PriceTier.FREE:
if config and config.setting and config.setting.price_tier == PriceTier.FREE:
return config.setting
# Fallback to the default chat model
return ConversationAdapters.get_default_chat_model(user)
@ -1213,13 +1213,13 @@ class ConversationAdapters:
)
if subscribed:
# Subscibed users can use any available chat model
if config:
if config and config.setting:
return config.setting
# Fallback to the default advanced chat model
return await ConversationAdapters.aget_advanced_chat_model(user)
else:
# Non-subscribed users can use any free chat model
if config and config.setting.price_tier == PriceTier.FREE:
if config and config.setting and config.setting.price_tier == PriceTier.FREE:
return config.setting
# Fallback to the default chat model
return await ConversationAdapters.aget_default_chat_model(user)