Skip to content

Commit 91603ae

Browse files
lfnovoclaude
andcommitted
fix(search): compare notebook scope ids as strings
The driver returns `id` as RecordID objects, which are unhashable and never equal to the request strings, so every real scoped request raised TypeError before reaching the search. Normalize to str before comparing and add a regression test that mocks RecordID rows. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014kRBoPiBD1NKeKHCo6EyrE
1 parent f05c153 commit 91603ae

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

open_notebook/domain/notebook.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,9 @@ async def resolve_notebook_scope(notebook_ids: List[str]) -> List[str]:
807807
logger.error(f"Error resolving notebook scope: {str(e)}")
808808
logger.exception(e)
809809
raise DatabaseOperationError("Failed to resolve notebook scope")
810-
found = {row["id"] for row in rows}
810+
# The driver returns ids as RecordID objects (unhashable, and never equal
811+
# to the request strings), so normalize to strings before comparing.
812+
found = {str(row["id"]) for row in rows}
811813
missing = [nb_id for nb_id in notebook_ids if nb_id not in found]
812814
if missing:
813815
raise NotFoundError(f"Notebook(s) not found: {', '.join(missing)}")

tests/test_search_api.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,23 @@ async def test_missing_notebooks_raise_not_found_listing_them(self):
435435
["notebook:a", "notebook:zzz"]
436436
)
437437

438+
@pytest.mark.asyncio
439+
async def test_record_id_rows_from_driver_match_request_strings(self):
440+
"""The real driver returns RecordID objects, not strings (regression)."""
441+
from surrealdb import RecordID
442+
443+
from open_notebook.domain import notebook as notebook_module
444+
445+
with patch.object(
446+
notebook_module,
447+
"repo_query",
448+
new_callable=AsyncMock,
449+
return_value=[{"id": RecordID("notebook", "a")}],
450+
):
451+
assert await notebook_module.resolve_notebook_scope(["notebook:a"]) == [
452+
"notebook:a"
453+
]
454+
438455

439456
class TestNotebookScopedSearchDomain:
440457
"""text_search / vector_search bind the scope as record ids (#574, #87)."""

0 commit comments

Comments
 (0)