fix: set_default_project skips config file update in cloud mode (#486)

Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Paul Hernandez
2025-12-30 09:05:48 -06:00
committed by GitHub
parent 537e58ad7d
commit fd732aa6fe
4 changed files with 27 additions and 43 deletions
+10 -8
View File
@@ -283,15 +283,17 @@ class ProjectService:
if not self.repository: # pragma: no cover
raise ValueError("Repository is required for set_default_project")
# First update config file (this will validate the project exists)
self.config_manager.set_default_project(name)
# Then update database using the same lookup logic as get_project
# Look up project in database first to validate it exists
project = await self.get_project(name)
if project:
await self.repository.set_as_default(project.id)
else:
logger.error(f"Project '{name}' exists in config but not in database")
if not project:
raise ValueError(f"Project '{name}' not found")
# Update database
await self.repository.set_as_default(project.id)
# Update config file only in local mode (cloud mode uses database only)
if not self.config_manager.config.cloud_mode:
self.config_manager.set_default_project(name)
logger.info(f"Project '{name}' set as default in configuration and database")
+8 -22
View File
@@ -17,9 +17,7 @@ class TestResolveProjectParameter:
mock_config = MagicMock()
mock_config.cloud_mode = True
with patch(
"basic_memory.mcp.project_context.ConfigManager"
) as mock_config_manager:
with patch("basic_memory.mcp.project_context.ConfigManager") as mock_config_manager:
mock_config_manager.return_value.config = mock_config
with pytest.raises(ValueError) as exc_info:
@@ -36,9 +34,7 @@ class TestResolveProjectParameter:
mock_config = MagicMock()
mock_config.cloud_mode = True
with patch(
"basic_memory.mcp.project_context.ConfigManager"
) as mock_config_manager:
with patch("basic_memory.mcp.project_context.ConfigManager") as mock_config_manager:
mock_config_manager.return_value.config = mock_config
result = await resolve_project_parameter(project=None, allow_discovery=True)
@@ -53,9 +49,7 @@ class TestResolveProjectParameter:
mock_config = MagicMock()
mock_config.cloud_mode = True
with patch(
"basic_memory.mcp.project_context.ConfigManager"
) as mock_config_manager:
with patch("basic_memory.mcp.project_context.ConfigManager") as mock_config_manager:
mock_config_manager.return_value.config = mock_config
result = await resolve_project_parameter(project="my-project")
@@ -70,9 +64,7 @@ class TestResolveProjectParameter:
mock_config = MagicMock()
mock_config.cloud_mode = False
with patch(
"basic_memory.mcp.project_context.ConfigManager"
) as mock_config_manager:
with patch("basic_memory.mcp.project_context.ConfigManager") as mock_config_manager:
mock_config_manager.return_value.config = mock_config
with patch.dict(os.environ, {"BASIC_MEMORY_MCP_PROJECT": "env-project"}):
@@ -90,9 +82,7 @@ class TestResolveProjectParameter:
mock_config.cloud_mode = False
mock_config.default_project_mode = False
with patch(
"basic_memory.mcp.project_context.ConfigManager"
) as mock_config_manager:
with patch("basic_memory.mcp.project_context.ConfigManager") as mock_config_manager:
mock_config_manager.return_value.config = mock_config
with patch.dict(os.environ, {}, clear=True):
@@ -112,9 +102,7 @@ class TestResolveProjectParameter:
mock_config.default_project_mode = True
mock_config.default_project = "default-project"
with patch(
"basic_memory.mcp.project_context.ConfigManager"
) as mock_config_manager:
with patch("basic_memory.mcp.project_context.ConfigManager") as mock_config_manager:
mock_config_manager.return_value.config = mock_config
with patch.dict(os.environ, {}, clear=True):
@@ -132,13 +120,11 @@ class TestResolveProjectParameter:
mock_config.cloud_mode = False
mock_config.default_project_mode = False
with patch(
"basic_memory.mcp.project_context.ConfigManager"
) as mock_config_manager:
with patch("basic_memory.mcp.project_context.ConfigManager") as mock_config_manager:
mock_config_manager.return_value.config = mock_config
with patch.dict(os.environ, {}, clear=True):
os.environ.pop("BASIC_MEMORY_MCP_PROJECT", None)
result = await resolve_project_parameter(project=None)
assert result is None
assert result is None
+5 -1
View File
@@ -106,7 +106,11 @@ def test_relation_response_with_null_permalink():
"permalink": "test/relation/123",
"relation_type": "relates_to",
"from_entity": {"permalink": None, "file_path": "notes/source-note.md"},
"to_entity": {"permalink": None, "file_path": "notes/target-note.md", "title": "Target Note"},
"to_entity": {
"permalink": None,
"file_path": "notes/target-note.md",
"title": "Target Note",
},
}
relation = RelationResponse.model_validate(data)
# Falls back to file_path directly (not converted to permalink)
+4 -12
View File
@@ -284,7 +284,7 @@ async def test_get_project_method(project_service: ProjectService):
async def test_set_default_project_config_db_mismatch(
project_service: ProjectService, config_manager: ConfigManager
):
"""Test set_default_project when project exists in config but not in database."""
"""Test set_default_project raises error when project exists in config but not in database."""
test_project_name = f"test-mismatch-project-{os.urandom(4).hex()}"
with tempfile.TemporaryDirectory() as temp_dir:
test_root = Path(temp_dir)
@@ -293,8 +293,6 @@ async def test_set_default_project_config_db_mismatch(
# Make sure the test directory exists
os.makedirs(test_project_path, exist_ok=True)
original_default = project_service.default_project
try:
# Add project to config only (not to database)
config_manager.add_project(test_project_name, test_project_path)
@@ -304,17 +302,11 @@ async def test_set_default_project_config_db_mismatch(
db_project = await project_service.repository.get_by_name(test_project_name)
assert db_project is None
# Try to set as default - this should trigger the error log on line 142
await project_service.set_default_project(test_project_name)
# Should still update config despite database mismatch
assert project_service.default_project == test_project_name
# Try to set as default - should raise ValueError since project not in database
with pytest.raises(ValueError, match=f"Project '{test_project_name}' not found"):
await project_service.set_default_project(test_project_name)
finally:
# Restore original default
if original_default:
config_manager.set_default_project(original_default)
# Clean up
if test_project_name in project_service.projects:
config_manager.remove_project(test_project_name)