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:
parent
09a0f786aa
commit
47c513edfd
8 changed files with 210 additions and 6 deletions
21
CHANGELOG.md
21
CHANGELOG.md
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)}")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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:**
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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"}
|
||||
|
|
|
|||
2
uv.lock
2
uv.lock
|
|
@ -2376,7 +2376,7 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "open-notebook"
|
||||
version = "1.6.0"
|
||||
version = "1.6.1"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "ai-prompter" },
|
||||
|
|
|
|||
Loading…
Reference in a new issue