From bb78f4ea80c13410fbf165bba983b2f84c3d5ab1 Mon Sep 17 00:00:00 2001 From: Steve Cliff Date: Mon, 6 Apr 2026 16:12:58 +0100 Subject: [PATCH] Fix 500 error on notes with slashes in title, bump engine to 3.2.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sanitize / and \ in note titles and filenames when writing to the staging directory — a title like "/reset skill" was interpreted as a path separator, causing a FileNotFoundError and a 500 from the jobs endpoint. Also add PRAGMA busy_timeout=5000 to SQLite connections to prevent immediate failure under concurrent write load. Co-Authored-By: Claude Opus 4.6 (1M context) --- engine/VERSION | 2 +- engine/kb/database.py | 1 + engine/kb/staging.py | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/engine/VERSION b/engine/VERSION index 944880f..e4604e3 100644 --- a/engine/VERSION +++ b/engine/VERSION @@ -1 +1 @@ -3.2.0 +3.2.1 diff --git a/engine/kb/database.py b/engine/kb/database.py index 05acec6..8a0c0dc 100644 --- a/engine/kb/database.py +++ b/engine/kb/database.py @@ -74,6 +74,7 @@ def get_connection(db_path: str) -> sqlite3.Connection: conn.enable_load_extension(False) conn.row_factory = sqlite3.Row conn.execute("PRAGMA journal_mode=WAL") + conn.execute("PRAGMA busy_timeout=5000") conn.execute("PRAGMA foreign_keys=ON") return conn diff --git a/engine/kb/staging.py b/engine/kb/staging.py index c84acaf..671d2c1 100644 --- a/engine/kb/staging.py +++ b/engine/kb/staging.py @@ -16,7 +16,8 @@ def stage_file(staging_dir: Path, filename: str, content: bytes) -> Path: The path to the newly created staged file. """ staging_dir.mkdir(parents=True, exist_ok=True) - dest = staging_dir / f"{uuid.uuid4()}_{filename}" + safe_filename = filename.replace("/", "_").replace("\\", "_") + dest = staging_dir / f"{uuid.uuid4()}_{safe_filename}" dest.write_bytes(content) logger.debug("Staged file: %s (%d bytes)", dest, len(content)) return dest @@ -31,7 +32,8 @@ def stage_note(staging_dir: Path, title: str, text: str) -> Path: The path to the newly created staged note file. """ staging_dir.mkdir(parents=True, exist_ok=True) - dest = staging_dir / f"{uuid.uuid4()}_{title}.note" + safe_title = title.replace("/", "_").replace("\\", "_") + dest = staging_dir / f"{uuid.uuid4()}_{safe_title}.note" dest.write_text(text, encoding="utf-8") logger.debug("Staged note: %s (%d chars)", dest, len(text)) return dest