Add a helpful error message when Fails fails to load indexes

We've had a few cases recently where Faiss is unable to load its
indexes properly, like after users upgrade versions of Llama Stack or
numpy dependencies. This catches any exceptions when deserializing the
index with an error message about what likely went wrong and how to
potentially fix it so that users can attempt to fix this without
needing to raise an issue or being confused.

The most common case of new users hitting this will be with the
SqliteKVStoreImpl, since that's our local storage most people use when
testing out Llama Stack. So, I added a `__str__` method to it that
shows the proper path and table name that users need to potentially
delete to resolve this error.

Signed-off-by: Ben Browning <bbrownin@redhat.com>
This commit is contained in:
Ben Browning 2025-06-27 14:16:05 -04:00
parent 6a3e8c0265
commit a5ebac18bd
2 changed files with 12 additions and 1 deletions

View file

@ -73,7 +73,15 @@ class FaissIndex(EmbeddingIndex):
self.chunk_by_index = {int(k): Chunk.model_validate_json(v) for k, v in data["chunk_by_index"].items()}
buffer = io.BytesIO(base64.b64decode(data["faiss_index"]))
self.index = faiss.deserialize_index(np.load(buffer, allow_pickle=False))
try:
self.index = faiss.deserialize_index(np.load(buffer, allow_pickle=False))
except Exception as e:
logger.debug(e, exc_info=True)
raise ValueError(
"Error deserializing Faiss index from storage. If you recently upgraded your Llama Stack, Faiss, "
"or NumPy versions, you may need to delete the index and re-create it again or downgrade versions.\n"
f"The problematic index is stored in the key value store {self.kvstore} under the key '{index_key}'."
) from e
async def _save_index(self):
if not self.kvstore or not self.bank_id:

View file

@ -18,6 +18,9 @@ class SqliteKVStoreImpl(KVStore):
self.db_path = config.db_path
self.table_name = "kvstore"
def __str__(self):
return f"SqliteKVStoreImpl(db_path={self.db_path}, table_name={self.table_name})"
async def initialize(self):
os.makedirs(os.path.dirname(self.db_path), exist_ok=True)
async with aiosqlite.connect(self.db_path) as db: