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/), 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). 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 ### Added
- Content-type aware text chunking with automatic HTML, Markdown, and plain text detection (#350, #142) - 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 - Unified embedding generation with mean pooling for large content that exceeds model context limits
- Dedicated embedding commands: `embed_note`, `embed_insight`, `embed_source` - Dedicated embedding commands: `embed_note`, `embed_insight`, `embed_source`
- New utility modules: `chunking.py` and `embedding.py` in `open_notebook/utils/` - New utility modules: `chunking.py` and `embedding.py` in `open_notebook/utils/`
- Japanese (ja-JP) language support (#450)
### Changed ### Changed
- Embedding is now fire-and-forget: domain models submit embedding commands asynchronously after save - 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 - `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 - 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 ### Removed
- Legacy embedding commands: `embed_single_item_command`, `embed_chunk_command`, `vectorize_source_command` - 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 ### Fixed
- Embedding failures when content exceeds model context limits (#350, #142) - 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 ## [1.5.2] - 2026-01-15

View file

@ -1,4 +1,5 @@
import asyncio import asyncio
import traceback
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from fastapi import APIRouter, HTTPException, Query from fastapi import APIRouter, HTTPException, Query
@ -381,7 +382,13 @@ async def execute_chat(request: ExecuteChatRequest):
except NotFoundError: except NotFoundError:
raise HTTPException(status_code=404, detail="Session not found") raise HTTPException(status_code=404, detail="Session not found")
except Exception as e: 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)}") raise HTTPException(status_code=500, detail=f"Error executing chat: {str(e)}")

View file

@ -233,6 +233,45 @@ ollama pull qwen3
## Troubleshooting ## 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 ### Common Issues
**1. "Ollama unavailable" in Open Notebook** **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 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 ### Docker-Specific Troubleshooting
**1. Host networking on Linux:** **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" ## "Models not available" or "Models not showing"
**Symptom:** Settings → Models shows empty, or "No models configured" **Symptom:** Settings → Models shows empty, or "No models configured"

View file

@ -187,9 +187,21 @@ class ModelManager:
model_id = defaults.large_context_model model_id = defaults.large_context_model
if not model_id: 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 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() model_manager = ModelManager()

View file

@ -16,17 +16,45 @@ async def provision_langchain_model(
Otherwise, returns the default model for the given type Otherwise, returns the default model for the given type
""" """
tokens = token_count(content) tokens = token_count(content)
model = None
selection_reason = ""
if tokens > 105_000: if tokens > 105_000:
selection_reason = f"large_context (content has {tokens} tokens)"
logger.debug( logger.debug(
f"Using large context model because the content has {tokens} tokens" f"Using large context model because the content has {tokens} tokens"
) )
model = await model_manager.get_default_model("large_context", **kwargs) model = await model_manager.get_default_model("large_context", **kwargs)
elif model_id: elif model_id:
selection_reason = f"explicit model_id={model_id}"
model = await model_manager.get_model(model_id, **kwargs) model = await model_manager.get_model(model_id, **kwargs)
else: else:
selection_reason = f"default for type={default_type}"
model = await model_manager.get_default_model(default_type, **kwargs) model = await model_manager.get_default_model(default_type, **kwargs)
logger.debug(f"Using model: {model}") 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() return model.to_langchain()

View file

@ -1,6 +1,6 @@
[project] [project]
name = "open-notebook" 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" description = "An open source implementation of a research assistant, inspired by Google Notebook LM"
authors = [ authors = [
{name = "Luis Novo", email = "lfnovo@gmail.com"} {name = "Luis Novo", email = "lfnovo@gmail.com"}

View file

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