fix: improve error logging for chat model configuration issues (#458)

* docs: update CHANGELOG for v1.6.0 release

* fix: improve error logging for chat model configuration issues (#358)

- Add detailed error logging in provision.py when model lookup fails
- Add warning logging in models.py when default model is not configured
- Add traceback logging in chat router exception handler
- Update Ollama docs with model name configuration guidance
- Update troubleshooting docs with "Failed to send message" solutions
- Bump version to 1.6.1

* chore: uvlock
This commit is contained in:
Luis Novo 2026-01-23 16:45:13 -03:00 committed by GitHub
parent 09a0f786aa
commit 47c513edfd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 210 additions and 6 deletions

View file

@ -5,18 +5,33 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.6.0] - 2026-01-16
## [1.6.1] - 2026-01-22
### Fixed
- "Failed to send message" error with unhelpful logs when chat model is not configured (#358)
- Added detailed error logging with model selection context and full traceback
- Improved error messages to guide users to Settings → Models
- Added warnings when default models are not configured
### Docs
- Ollama troubleshooting: Added "Model Name Configuration" section emphasizing exact model names from `ollama list`
- Added troubleshooting entry for "Failed to send message" error with step-by-step solutions
- Updated AI Chat Issues documentation with model configuration guidance
## [1.6.0] - 2026-01-21
### Added
- Content-type aware text chunking with automatic HTML, Markdown, and plain text detection (#350, #142)
- Unified embedding generation with mean pooling for large content that exceeds model context limits
- Dedicated embedding commands: `embed_note`, `embed_insight`, `embed_source`
- New utility modules: `chunking.py` and `embedding.py` in `open_notebook/utils/`
- Japanese (ja-JP) language support (#450)
### Changed
- Embedding is now fire-and-forget: domain models submit embedding commands asynchronously after save
- `rebuild_embeddings_command` now delegates to individual embed_* commands instead of inline processing
- Chunk size reduced to 1500 characters for better compatibility with Ollama embedding models
- Bump Esperanto to 2.16 for increased Ollama context window support
### Removed
- Legacy embedding commands: `embed_single_item_command`, `embed_chunk_command`, `vectorize_source_command`
@ -25,6 +40,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Embedding failures when content exceeds model context limits (#350, #142)
- Empty note titles when saving from chat (clean thinking tags from prompt graph output)
- Orphaned embedding/insight records when deleting sources (cascade delete)
- Search results crash with null parent_id (defensive frontend check)
- Database migration 10 cleans up existing orphaned records
## [1.5.2] - 2026-01-15

View file

@ -1,4 +1,5 @@
import asyncio
import traceback
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, HTTPException, Query
@ -381,7 +382,13 @@ async def execute_chat(request: ExecuteChatRequest):
except NotFoundError:
raise HTTPException(status_code=404, detail="Session not found")
except Exception as e:
logger.error(f"Error executing chat: {str(e)}")
# Log detailed error with context for debugging
logger.error(
f"Error executing chat: {str(e)}\n"
f" Session ID: {request.session_id}\n"
f" Model override: {request.model_override}\n"
f" Traceback:\n{traceback.format_exc()}"
)
raise HTTPException(status_code=500, detail=f"Error executing chat: {str(e)}")

View file

@ -233,6 +233,45 @@ ollama pull qwen3
## Troubleshooting
### Model Name Configuration (Critical)
**⚠️ IMPORTANT: Model names must exactly match the output of `ollama list`**
This is the most common cause of "Failed to send message" errors. Open Notebook requires the **exact model name** as it appears in Ollama.
**Step 1: Get the exact model name**
```bash
ollama list
```
Example output:
```
NAME ID SIZE MODIFIED
mxbai-embed-large:latest 468836162de7 669 MB 7 minutes ago
gemma3:12b f4031aab637d 8.1 GB 2 months ago
qwen3:32b 030ee887880f 20 GB 9 days ago
```
**Step 2: Use the exact name when adding the model in Open Notebook**
| ✅ Correct | ❌ Wrong |
|-----------|----------|
| `gemma3:12b` | `gemma3` (missing tag) |
| `qwen3:32b` | `qwen3-32b` (wrong format) |
| `mxbai-embed-large:latest` | `mxbai-embed-large` (missing tag) |
**Note:** Some models use `:latest` as the default tag. If `ollama list` shows `model:latest`, you must use `model:latest` in Open Notebook, not just `model`.
**Step 3: Configure in Open Notebook**
1. Go to **Settings → Models**
2. Click **Add Model**
3. Enter the **exact name** from `ollama list`
4. Select provider: `ollama`
5. Select type: `language` (for chat) or `embedding` (for search)
6. Save the model
7. Set it as the default for the appropriate task (chat, transformation, etc.)
### Common Issues
**1. "Ollama unavailable" in Open Notebook**
@ -324,6 +363,50 @@ OLLAMA_HOST=0.0.0.0:8080 ollama serve
export OLLAMA_API_BASE=http://localhost:8080
```
**6. "Failed to send message" in Chat**
**Symptom:** Chat shows "Failed to send message" toast notification. Logs may show:
```
Error executing chat: Model is not a LanguageModel: None
```
**Causes (in order of likelihood):**
1. **Model name mismatch**: The model name in Open Notebook doesn't exactly match `ollama list`
2. **No default model configured**: You haven't set a default chat model in Settings → Models
3. **Model was deleted**: You removed the model from Ollama but didn't update Open Notebook's defaults
4. **Model record deleted**: The model was removed from Open Notebook but is still set as default
**Solutions:**
**Check 1: Verify model names match exactly**
```bash
# Get exact model names from Ollama
ollama list
# Compare with what's configured in Open Notebook
# Go to Settings → Models and verify the names match EXACTLY
```
**Check 2: Verify default models are set**
1. Go to **Settings → Models**
2. Scroll to **Default Models** section
3. Ensure **Default Chat Model** has a value selected
4. If empty, select an available language model
**Check 3: Refresh after changes**
If you've added/removed models in Ollama:
1. Refresh the Open Notebook page
2. Go to Settings → Models
3. Re-add any missing models with exact names from `ollama list`
4. Re-select default models if needed
**Check 4: Test the model directly**
```bash
# Verify Ollama can use the model
ollama run gemma3:12b "Hello, world"
```
### Docker-Specific Troubleshooting
**1. Host networking on Linux:**

View file

@ -4,6 +4,61 @@ Problems with AI models, chat, and response quality.
---
## "Failed to send message" Error
**Symptom:** Chat shows "Failed to send message" toast. Logs show:
```
Error executing chat: Model is not a LanguageModel: None
```
**Cause:** No valid language model configured for chat
**Solutions:**
### Solution 1: Check Default Model Configuration
```
1. Go to Settings → Models
2. Scroll to "Default Models" section
3. Verify "Default Chat Model" has a model selected
4. If empty, select an available language model
5. Click Save
```
### Solution 2: Verify Model Names (Ollama Users)
```bash
# Get exact model names
ollama list
# Example output:
# NAME SIZE MODIFIED
# gemma3:12b 8.1 GB 2 months ago
# The model name in Open Notebook must be EXACTLY "gemma3:12b"
# NOT "gemma3" or "gemma3-12b"
```
### Solution 3: Re-add Missing Models
```
1. Note the exact model names from your provider
2. Go to Settings → Models
3. Delete any misconfigured models
4. Add models with exact names
5. Set new defaults
```
### Solution 4: Check Model Still Exists
```bash
# For Ollama: verify model is installed
ollama list
# For cloud providers: verify API key is valid
# and you have access to the model
```
> **Tip:** This error often occurs when you delete a model from Ollama but forget to update the default models in Open Notebook. Always re-configure defaults after removing models.
---
## "Models not available" or "Models not showing"
**Symptom:** Settings → Models shows empty, or "No models configured"

View file

@ -187,9 +187,21 @@ class ModelManager:
model_id = defaults.large_context_model
if not model_id:
logger.warning(
f"No default model configured for type '{model_type}'. "
f"Please go to Settings → Models and set a default model."
)
return None
return await self.get_model(model_id, **kwargs)
try:
return await self.get_model(model_id, **kwargs)
except ValueError as e:
logger.error(
f"Failed to load default model for type '{model_type}': {e}. "
f"The configured model_id '{model_id}' may have been deleted or misconfigured. "
f"Please go to Settings → Models and reconfigure the default model."
)
return None
model_manager = ModelManager()

View file

@ -16,17 +16,45 @@ async def provision_langchain_model(
Otherwise, returns the default model for the given type
"""
tokens = token_count(content)
model = None
selection_reason = ""
if tokens > 105_000:
selection_reason = f"large_context (content has {tokens} tokens)"
logger.debug(
f"Using large context model because the content has {tokens} tokens"
)
model = await model_manager.get_default_model("large_context", **kwargs)
elif model_id:
selection_reason = f"explicit model_id={model_id}"
model = await model_manager.get_model(model_id, **kwargs)
else:
selection_reason = f"default for type={default_type}"
model = await model_manager.get_default_model(default_type, **kwargs)
logger.debug(f"Using model: {model}")
assert isinstance(model, LanguageModel), f"Model is not a LanguageModel: {model}"
if model is None:
logger.error(
f"Model provisioning failed: No model found. "
f"Selection reason: {selection_reason}. "
f"model_id={model_id}, default_type={default_type}. "
f"Please check Settings → Models and ensure a default model is configured for '{default_type}'."
)
raise ValueError(
f"No model configured for {selection_reason}. "
f"Please go to Settings → Models and configure a default model for '{default_type}'."
)
if not isinstance(model, LanguageModel):
logger.error(
f"Model type mismatch: Expected LanguageModel but got {type(model).__name__}. "
f"Selection reason: {selection_reason}. "
f"model_id={model_id}, default_type={default_type}."
)
raise ValueError(
f"Model is not a LanguageModel: {model}. "
f"Please check that the model configured for '{default_type}' is a language model, not an embedding or speech model."
)
return model.to_langchain()

View file

@ -1,6 +1,6 @@
[project]
name = "open-notebook"
version = "1.6.0"
version = "1.6.1"
description = "An open source implementation of a research assistant, inspired by Google Notebook LM"
authors = [
{name = "Luis Novo", email = "lfnovo@gmail.com"}

View file

@ -2376,7 +2376,7 @@ wheels = [
[[package]]
name = "open-notebook"
version = "1.6.0"
version = "1.6.1"
source = { editable = "." }
dependencies = [
{ name = "ai-prompter" },