fix: resolve default_project returning null in cloud mode (#644)

In cloud mode, ConfigManager has no local config file so
default_project always returned None. Add async
get_default_project_name() on ProjectService that falls back
to the database is_default flag when ConfigManager returns None.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
This commit is contained in:
phernandez
2026-03-04 11:57:15 -06:00
parent d15f6a8427
commit 195229f78e
3 changed files with 34 additions and 3 deletions
@@ -48,7 +48,7 @@ async def list_projects(
A list of all projects with metadata
"""
projects = await project_service.list_projects()
default_project = project_service.default_project
default_project = await project_service.get_default_project_name()
project_items = [
ProjectItem(
@@ -82,6 +82,21 @@ class ProjectService:
"""
return self.config_manager.default_project
async def get_default_project_name(self) -> str:
"""Get the default project name, falling back to the database.
ConfigManager reads from the local config file, which doesn't exist
in cloud mode. When it returns None, fall back to the is_default
flag stored in the database.
"""
default = self.config_manager.default_project
if default is not None:
return default
db_default = await self.repository.get_default_project()
if db_default is not None:
return db_default.name
raise ValueError("No default project configured")
@property
def current_project(self) -> Optional[str]:
"""Get the name of the currently active project.
+18 -2
View File
@@ -11,6 +11,21 @@ from basic_memory.schemas.project_info import ProjectItem, ProjectStatusResponse
from basic_memory.schemas.v2 import ProjectResolveResponse
@pytest.mark.asyncio
async def test_list_projects(client: AsyncClient, test_project: Project, v2_projects_url):
"""Test listing projects returns default_project from the database."""
response = await client.get(f"{v2_projects_url}/")
assert response.status_code == 200
data = response.json()
# default_project must be populated from the is_default flag in the database
assert data["default_project"] == test_project.name
project_names = [p["name"] for p in data["projects"]]
assert test_project.name in project_names
@pytest.mark.asyncio
async def test_get_project_by_id(client: AsyncClient, test_project: Project, v2_projects_url):
"""Test getting a project by its external_id UUID."""
@@ -361,9 +376,10 @@ async def test_legacy_v1_list_projects_endpoint(client: AsyncClient, test_projec
assert response.status_code == 200
data = response.json()
assert "projects" in data
assert "default_project" in data
# Verify the test project is in the list
# default_project must be populated, not null
assert data["default_project"] == test_project.name
project_names = [p["name"] for p in data["projects"]]
assert test_project.name in project_names