FoundationAgents/MetaGPT · error · ValueError
Invalid root
Error message
Invalid root
What it means
Raised by ProjectRepo.__init__: the constructor accepts only a str/Path (treated as the local git path, wrapped into GitRepository) or an existing GitRepository instance; anything else (None, a Config object, a repo object of another type) hits the else-branch and is rejected.
Source
Thrown at metagpt/utils/project_repo.py:99
self.data_api_design = git_repo.new_file_repository(relative_path=DATA_API_DESIGN_FILE_REPO)
self.seq_flow = git_repo.new_file_repository(relative_path=SEQ_FLOW_FILE_REPO)
self.system_design = git_repo.new_file_repository(relative_path=SYSTEM_DESIGN_PDF_FILE_REPO)
self.prd = git_repo.new_file_repository(relative_path=PRD_PDF_FILE_REPO)
self.api_spec_and_task = git_repo.new_file_repository(relative_path=TASK_PDF_FILE_REPO)
self.code_summary = git_repo.new_file_repository(relative_path=CODE_SUMMARIES_PDF_FILE_REPO)
self.sd_output = git_repo.new_file_repository(relative_path=SD_OUTPUT_FILE_REPO)
self.code_plan_and_change = git_repo.new_file_repository(relative_path=CODE_PLAN_AND_CHANGE_PDF_FILE_REPO)
self.graph_repo = git_repo.new_file_repository(relative_path=VISUAL_GRAPH_REPO_FILE_REPO)
class ProjectRepo(FileRepository):
def __init__(self, root: str | Path | GitRepository):
if isinstance(root, str) or isinstance(root, Path):
git_repo_ = GitRepository(local_path=Path(root))
elif isinstance(root, GitRepository):
git_repo_ = root
else:
raise ValueError("Invalid root")
super().__init__(git_repo=git_repo_, relative_path=Path("."))
self._git_repo = git_repo_
self.docs = DocFileRepositories(self._git_repo)
self.resources = ResourceFileRepositories(self._git_repo)
self.tests = self._git_repo.new_file_repository(relative_path=TEST_CODES_FILE_REPO)
self.test_outputs = self._git_repo.new_file_repository(relative_path=TEST_OUTPUTS_FILE_REPO)
self._srcs_path = None
self.code_files_exists()
def __str__(self):
repo_str = f"ProjectRepo({self._git_repo.workdir})"
docs_str = f"Docs({self.docs.all_files})"
srcs_str = f"Srcs({self.srcs.all_files})"
return f"{repo_str}\n{docs_str}\n{srcs_str}"
@property
async def requirement(self):
return await self.docs.get(filename=REQUIREMENT_FILENAME)View on GitHub (pinned to 11cdf466d0)
Solutions
- Pass a valid path: ProjectRepo('/path/to/repo') or ProjectRepo(Path(...)).
- Or pass the GitRepository object itself: ProjectRepo(ctx.git_repo) after ensuring it is not None.
- If the value may be None, initialize a GitRepository first: ProjectRepo(GitRepository(local_path=Path.cwd())).
Example fix
# before repo = ProjectRepo(ctx.git_repo) # ctx.git_repo is None -> ValueError # after from metagpt.utils.git_repository import GitRepository repo = ProjectRepo(ctx.git_repo or GitRepository(local_path=Path.cwd()))
Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import Path
from metagpt.utils.git_repository import GitRepository
assert isinstance(root, (str, Path, GitRepository)) and root is not None, \
'ProjectRepo root must be str/Path/GitRepository' Type guard
def is_project_repo_root(root) -> bool:
return isinstance(root, (str, Path)) or root.__class__.__name__ == 'GitRepository' Try / catch
try:
repo = ProjectRepo(root)
except ValueError:
repo = ProjectRepo(Path.cwd()) # sensible default local path Prevention
- Initialize Context.git_repo before passing it to ProjectRepo.
- Pass explicit absolute paths in scripts/tests.
- Guard optional values: `root or Path.cwd()`.
When it happens
Trigger: ProjectRepo(None) when an upstream variable is unset; ProjectRepo(ctx.git_repo) where git_repo was never initialized; passing a string-like custom object that is not str/Path.
Common situations: Contexts where the git repository was expected to be initialized earlier in the flow (e.g. a Context/Env whose git_repo attribute is None), or API changes where callers now must pass a GitRepository rather than something else.
Related errors
- Call with_srcs first.
- Only support message type are: str, Message, dict, but got {
- No file open. Use the open_file function first.
- File {path} not found
- Line number must be between 1 and {total_lines}
AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14).
Data as JSON: /api/errors/1c22919c07efc8c7.
Report an issue: GitHub.