FoundationAgents/MetaGPT · error · ValueError

invalid stage: {stage}, mode: {mode}

Error message

invalid stage: {stage}, mode: {mode}

What it means

Raised by AndroidAssistant.__init__ when the `stage`/`mode` values from the run config do not match any supported combination. Supported branches are stage='learn' with mode='manual' or 'auto', and stage='act' (any mode). Any other stage value (or a missing stage) falls into the else and raises.

Source

Thrown at metagpt/ext/android_assistant/roles/android_assistant.py:75

            # Remember, only run each action only one time, no need to run n_round.
            self.set_actions([ManualRecord, ParseRecord])
            self.task_dir = data_dir.joinpath(app_name, f"manual_learn_{cur_datetime}")
            self.docs_dir = data_dir.joinpath(app_name, "manual_docs")
        elif stage == "learn" and mode == "auto":
            # choose SelfLearnAndReflect to run
            self.set_actions([SelfLearnAndReflect])
            self.task_dir = data_dir.joinpath(app_name, f"auto_learn_{cur_datetime}")
            self.docs_dir = data_dir.joinpath(app_name, "auto_docs")
        elif stage == "act":
            # choose ScreenshotParse to run
            self.set_actions([ScreenshotParse])
            self.task_dir = data_dir.joinpath(app_name, f"act_{cur_datetime}")
            if mode == "manual":
                self.docs_dir = data_dir.joinpath(app_name, "manual_docs")
            else:
                self.docs_dir = data_dir.joinpath(app_name, "auto_docs")
        else:
            raise ValueError(f"invalid stage: {stage}, mode: {mode}")

        self._check_dir()

        self._set_react_mode(RoleReactMode.BY_ORDER)

    def _check_dir(self):
        self.task_dir.mkdir(parents=True, exist_ok=True)
        self.docs_dir.mkdir(parents=True, exist_ok=True)

    async def react(self) -> Message:
        self.round_count += 1
        result = await super().react()
        logger.debug(f"react result {result}")
        return result

    async def _observe(self, ignore_memory=True) -> int:
        """ignore old memory to make it run multi rounds inside a role"""
        newest_msgs = self.rc.memory.get(k=1)

View on GitHub (pinned to 11cdf466d0)

Solutions

  1. Set stage to 'learn' (with mode 'manual' or 'auto') or 'act' in the extra config
  2. Check that the config key is exactly 'stage' under extra_config, not nested elsewhere or misspelled
  3. Run a documented example config first to confirm the expected keys

Example fix

# before
extra_config = {"app_name": "demo", "stage": "run"}

# after
extra_config = {"app_name": "demo", "stage": "act", "mode": "auto"}
Defensive patterns

Strategy: validation

Validate before calling

extra = {"stage": "learn", "mode": "auto", "app_name": "demo"}
assert extra.get("stage") in {"learn", "act"}
assert extra.get("stage") != "learn" or extra.get("mode") in {"manual", "auto"}

Type guard

def is_valid_stage_mode(extra: dict) -> bool:
    stage, mode = extra.get("stage"), extra.get("mode")
    return stage == "act" or (stage == "learn" and mode in ("manual", "auto"))

Prevention

When it happens

Trigger: Running the android assistant with extra_config stage not in {'learn','act'}, e.g. stage='test', stage=None (key omitted from the config), or a typo like 'acting'.

Common situations: Copied example config missing the 'stage' key; typo in the YAML/CLI value; expecting an undocumented stage such as 'eval'.

Related errors


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