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

  1. Pass a valid path: ProjectRepo('/path/to/repo') or ProjectRepo(Path(...)).
  2. Or pass the GitRepository object itself: ProjectRepo(ctx.git_repo) after ensuring it is not None.
  3. 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

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


AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14). Data as JSON: /api/errors/1c22919c07efc8c7. Report an issue: GitHub.