{"record":{"id":"99d67a09a5226cf6","repo":"FoundationAgents/MetaGPT","slug":"insufficient-funds-self-cost-manager-max-budget","errorCode":null,"errorMessage":"Insufficient funds: {self.cost_manager.max_budget}","messagePattern":"Insufficient funds: (.+?)","errorType":"exception","errorClass":"NoMoneyException","httpStatus":null,"severity":"error","filePath":"metagpt/team.py","lineNumber":100,"sourceCode":"\n    def hire(self, roles: list[Role]):\n        \"\"\"Hire roles to cooperate\"\"\"\n        self.env.add_roles(roles)\n\n    @property\n    def cost_manager(self):\n        \"\"\"Get cost manager\"\"\"\n        return self.env.context.cost_manager\n\n    def invest(self, investment: float):\n        \"\"\"Invest company. raise NoMoneyException when exceed max_budget.\"\"\"\n        self.investment = investment\n        self.cost_manager.max_budget = investment\n        logger.info(f\"Investment: ${investment}.\")\n\n    def _check_balance(self):\n        if self.cost_manager.total_cost >= self.cost_manager.max_budget:\n            raise NoMoneyException(self.cost_manager.total_cost, f\"Insufficient funds: {self.cost_manager.max_budget}\")\n\n    def run_project(self, idea, send_to: str = \"\"):\n        \"\"\"Run a project from publishing user requirement.\"\"\"\n        self.idea = idea\n\n        # Human requirement.\n        self.env.publish_message(Message(content=idea))\n\n    def start_project(self, idea, send_to: str = \"\"):\n        \"\"\"\n        Deprecated: This method will be removed in the future.\n        Please use the `run_project` method instead.\n        \"\"\"\n        warnings.warn(\n            \"The 'start_project' method is deprecated and will be removed in the future. \"\n            \"Please use the 'run_project' method instead.\",\n            DeprecationWarning,\n            stacklevel=2,","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/FoundationAgents/MetaGPT/blob/11cdf466d042aece04fc6cfd13b28e1a70341b1f/metagpt/team.py#L82-L118","documentation":"Team._check_balance compares the CostManager's accumulated total_cost against max_budget (set by Team.invest). When spend reaches or exceeds the budget, it raises NoMoneyException with the budget in the message. This is the run loop's hard stop for API spending.","triggerScenarios":"company.invest(0.5) then running enough LLM calls that total_cost >= 0.5; also fires when investment was never raised from a tiny default while running a full software-company pipeline.","commonSituations":"Setting --investment too low for the number of roles/rounds; long PRD+design+code runs consuming many tokens; expensive models (e.g. large-context GPT-4 class) exhausting a small budget quickly.","solutions":["Raise the budget: company.invest(10.0) or metagpt --investment 10.0 and re-run/recover","Use cheaper llm models in config (api_type/model settings) to slow spend","Reduce n_round or number of hired roles to cap total LLM calls"],"exampleFix":"// before\ncompany.invest(0.5)  # NoMoneyException mid-run\n\n// after\ncompany.invest(10.0)\nawait company.run(n_round=n_round, idea=idea)","handlingStrategy":"try-catch","validationCode":"if company.cost_manager.total_cost + estimated_run_cost > company.cost_manager.max_budget:\n    company.invest(company.cost_manager.total_cost + estimated_run_cost + buffer)","typeGuard":null,"tryCatchPattern":"from metagpt.exception import NoMoneyException\ntry:\n    await company.run(n_round=n_round, idea=idea)\nexcept NoMoneyException:\n    company.invest(company.cost_manager.max_budget * 2)  # top up and resume via --recover-path\n    logger.warning(\"budget exhausted; re-run with --recover-path to continue\")","preventionTips":["Call company.invest with a realistic budget before run (default is tiny)","Monitor cost_manager.total_cost periodically during long runs","Use --recover-path after a NoMoneyException so completed work is not lost","Prefer cheaper models for drafts to preserve budget"],"tags":["budget","cost","llm","team"],"backgroundTag":null,"analyzedSha":"11cdf466d042aece04fc6cfd13b28e1a70341b1f","analyzedAt":"2026-08-14T23:20:02.994Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}