You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Flaky CI: watcher lifecycle integration test and Postgres refresh negative control #1955
A negative control that requires a race to happen is timing-dependent on shared runners.
Fix direction
Lifecycle test: find the wait that can outlast its deadline under load; isolate _initial_index_tasks per test.
Negative control: force the overlap deterministically (e.g. an explicit barrier between the two refreshes) instead of relying on timing, or drop it if the positive tests cover the tolerance.
Component: Testing (watcher/indexing lifecycle and Postgres search refresh). Not Cloud-specific.
Priority: Medium. Nothing breaks for users, but the flakes fail unrelated PRs and cost a re-run each time.
Complexity: Medium. The two tests need separate fixes.
Duplicates: None found. #940 covers a similar class (timing-sensitive tests) but different tests, and it is closed.
Notes
Lifecycle test (test-int/mcp/test_new_project_watch_lifecycle.py): the issue already names a likely cause. The module-global _initial_index_tasks is shared across tests, and a fake _CapturedTask from tests/services/test_initialization.py can be gathered in this test's teardown. That would explain the TypeError and may also explain the teardown hang. The asyncio.timeout failures seen on SQLite shard 2/2 could be a separate load-sensitive wait, so fix both: isolate the task set per test and review the wait deadlines.
Negative control (tests/services/test_search_refresh_concurrency.py): it asserts that a race happens, so it depends on timing. The issue's suggestion of an explicit barrier or event between the two refreshes is the right fix. If the positive tests already cover the tolerance, dropping the control is also fine.
No reproduction steps are needed. The CI run links are in the issue. I've stopped at triage and made no code changes.
Two more failures on 2026-10-29, now with a third symptom: bm_search raising sqlite3.OperationalError: vtable constructor failed: search_index inside the watcher lifecycle test.
main at ab6a059 (fix(core): rank an exact title match first in title search #1957 merge): test_new_project_copied_files_and_live_changes_are_searchable. In the same run, test-int/test_sqlite_lifecycle_integration.py::test_file_sqlite_concurrent_writes_commit_and_dispose also failed with an OperationalError.
A virtual-table constructor failure on an FTS5 table points at the search_index being created or dropped concurrently while another connection opens it. The watcher's new-project catch-up may be (re)creating search tables while the test searches.
Another occurrence on main at 1e8e64c (run 40970750756, SQLite integration shard 2/2): test_new_project_copied_files_and_live_changes_are_searchable timed out at line 83, the narwhal loop. The first loop (copied file indexed after attach) passed, so the project was attached and only the later live edit was missed. Same symptom as described above; the next main run (fb90bbb) passed.
Activity
claude commentedon Oct 29, 2026
Claude finished @phernandez's task in 14s —— View job
Triage
Duplicates: None found. #940 covers a similar class (timing-sensitive tests) but different tests, and it is closed.
Notes
test-int/mcp/test_new_project_watch_lifecycle.py): the issue already names a likely cause. The module-global_initial_index_tasksis shared across tests, and a fake_CapturedTaskfromtests/services/test_initialization.pycan be gathered in this test's teardown. That would explain theTypeErrorand may also explain the teardown hang. Theasyncio.timeoutfailures seen on SQLite shard 2/2 could be a separate load-sensitive wait, so fix both: isolate the task set per test and review the wait deadlines.tests/services/test_search_refresh_concurrency.py): it asserts that a race happens, so it depends on timing. The issue's suggestion of an explicit barrier or event between the two refreshes is the right fix. If the positive tests already cover the tolerance, dropping the control is also fine.No reproduction steps are needed. The CI run links are in the issue. I've stopped at triage and made no code changes.
phernandez commentedon Oct 29, 2026
Two more failures on 2026-10-29, now with a third symptom:
bm_searchraisingsqlite3.OperationalError: vtable constructor failed: search_indexinside the watcher lifecycle test.test_new_project_copied_files_and_live_changes_are_searchable. In the same run,test-int/test_sqlite_lifecycle_integration.py::test_file_sqlite_concurrent_writes_commit_and_disposealso failed with an OperationalError.A virtual-table constructor failure on an FTS5 table points at the search_index being created or dropped concurrently while another connection opens it. The watcher's new-project catch-up may be (re)creating search tables while the test searches.
fix(core): own startup index tasks and remove flaky test causes (#1967)
phernandez commentedon Oct 29, 2026
Another occurrence on main at 1e8e64c (run 40970750756, SQLite integration shard 2/2):
test_new_project_copied_files_and_live_changes_are_searchabletimed out at line 83, thenarwhalloop. The first loop (copied file indexed after attach) passed, so the project was attached and only the later live edit was missed. Same symptom as described above; the next main run (fb90bbb) passed.test(sync): remove the flaky new-project watch lifecycle test