FoundationAgents/MetaGPT · error · RuntimeError

SPO_LLM not initialized. Call initialize() first.

Error message

SPO_LLM not initialized. Call initialize() first.

What it means

SPO_LLM is a singleton with a lazily set class-level _instance; get_instance() raises RuntimeError if initialize(optimize_kwargs, evaluate_kwargs, execute_kwargs) has not been called yet in the process. It guards against using the SPO pipeline before its three LLM roles are configured.

Source

Thrown at metagpt/ext/spo/utils/llm_client.py:76

        }

        llm = llm_mapping.get(request_type)
        if not llm:
            raise ValueError(f"Invalid request type. Valid types: {', '.join([t.value for t in RequestType])}")

        response = await llm.acompletion(messages)
        return response.choices[0].message.content

    @classmethod
    def initialize(cls, optimize_kwargs: dict, evaluate_kwargs: dict, execute_kwargs: dict) -> None:
        """Initialize the global instance"""
        cls._instance = cls(optimize_kwargs, evaluate_kwargs, execute_kwargs)

    @classmethod
    def get_instance(cls) -> "SPO_LLM":
        """Get the global instance"""
        if cls._instance is None:
            raise RuntimeError("SPO_LLM not initialized. Call initialize() first.")
        return cls._instance


def extract_content(xml_string: str, tag: str) -> Optional[str]:
    pattern = rf"<{tag}>(.*?)</{tag}>"
    match = re.search(pattern, xml_string, re.DOTALL)
    return match.group(1).strip() if match else None


async def main():
    # test LLM
    SPO_LLM.initialize(
        optimize_kwargs={"model": "gpt-4o", "temperature": 0.7},
        evaluate_kwargs={"model": "gpt-4o-mini", "temperature": 0.3},
        execute_kwargs={"model": "gpt-4o-mini", "temperature": 0.3},
    )

    llm = SPO_LLM.get_instance()

View on GitHub (pinned to 11cdf466d0)

Solutions

  1. Call SPO_LLM.initialize(optimize_kwargs, evaluate_kwargs, execute_kwargs) once at startup, before any component that uses get_instance().
  2. If it may already be initialized (notebooks, repeated runs), guard with a check on SPO_LLM._instance before calling initialize.
  3. In tests, put initialize in a fixture/setup so every test session has the singleton configured.

Example fix

// before
llm = SPO_LLM.get_instance()  # RuntimeError: not initialized

// after
SPO_LLM.initialize(
    optimize_kwargs={"model": "gpt-4o"},
    evaluate_kwargs={"model": "gpt-4o-mini"},
    execute_kwargs={"model": "gpt-4o-mini"},
)
llm = SPO_LLM.get_instance()
Defensive patterns

Strategy: validation

Validate before calling

from metagpt.ext.spo.utils.llm_client import SPO_LLM

def ensure_spo_llm(**kwargs_sets) -> SPO_LLM:
    if SPO_LLM._instance is None:
        SPO_LLM.initialize(**kwargs_sets)
    return SPO_LLM.get_instance()

Try / catch

try:
    llm = SPO_LLM.get_instance()
except RuntimeError as e:
    if "not initialized" in str(e):
        SPO_LLM.initialize(opt_kwargs, eva_kwargs, exe_kwargs)
        llm = SPO_LLM.get_instance()
    else:
        raise

Prevention

When it happens

Trigger: Calling SPO_LLM.get_instance() (directly, or indirectly via the SPO evaluator/optimizer components) before any SPO_LLM.initialize(...) call; running in a fresh subprocess or after resetting the class where initialize was skipped.

Common situations: Starting a new Python session / notebook kernel and jumping straight to prompt optimization; scripts that import the pipeline components but only conditionally call initialize; tests that instantiate SPO objects without the global setup.

Related errors


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