From 6690953480787f64ba0e4431a05114ff0f045164 Mon Sep 17 00:00:00 2001 From: Yiorgis Gozadinos Date: Wed, 20 May 2026 16:47:57 +0300 Subject: [PATCH] fix mxbai reranker crash in chat TUI --- CHANGELOG.md | 4 ++++ haiku_rag_slim/haiku/rag/reranking/mxbai.py | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c45b996..df8b76f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ - Documentation generator swapped from `mkdocs-material` to `zensical`. Drops `mkdocs` / `mkdocs-material` dev deps, replaces `mkdocs.yml` with `zensical.toml`, adds `overrides/main.html` (OG/Twitter share meta) and `docs/stylesheets/extra.css`. `build-docs` workflow now runs `uv run zensical build` and publishes via the GitHub Pages artifact actions instead of `mkdocs gh-deploy`. +### Fixed + +- mxbai reranker crashing inside the chat TUI with `ValueError: bad value(s) in fds_to_keep`. tqdm constructs a `multiprocessing.RLock` on first use, whose `resource_tracker` spawn picks up `sys.stderr.fileno()`; Textual's redirected stderr returns `-1`, failing the `fork_exec` validation. The reranker now pins tqdm's class lock to a `threading.RLock`. + ## [0.48.0] - 2026-05-20 ### Added diff --git a/haiku_rag_slim/haiku/rag/reranking/mxbai.py b/haiku_rag_slim/haiku/rag/reranking/mxbai.py index d73ed751..01ef50b9 100644 --- a/haiku_rag_slim/haiku/rag/reranking/mxbai.py +++ b/haiku_rag_slim/haiku/rag/reranking/mxbai.py @@ -1,11 +1,20 @@ import asyncio +import threading +import tqdm from mxbai_rerank import MxbaiRerankV2 # pyright: ignore[reportMissingImports] from haiku.rag.config import Config from haiku.rag.reranking.base import RerankerBase from haiku.rag.store.models.chunk import Chunk +# tqdm's default class lock is a multiprocessing.RLock; constructing it spawns +# resource_tracker, which inherits sys.stderr's fileno. Inside Textual's chat +# TUI, sys.stderr.fileno() returns -1, landing in fds_to_keep and failing the +# fork_exec validation. A threading lock is sufficient since we never share +# tqdm progress bars across processes. +tqdm.tqdm.set_lock(threading.RLock()) + class MxBAIReranker(RerankerBase): def __init__(self):