microsoft/autogen · error · ValueError

Cannot serialize CodeExecutorAgent with approval_func set. T

Error message

Cannot serialize CodeExecutorAgent with approval_func set. The approval function is not serializable.

What it means

CodeExecutorAgent._to_config() refuses to serialize the agent when an approval_func is set, because a Python callback function cannot be represented in the declarative component config. dump_component()/save state will therefore fail.

Source

Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/agents/_code_executor_agent.py:745

        return result

    async def on_reset(self, cancellation_token: CancellationToken) -> None:
        """Its a no-op as the code executor agent has no mutable state."""
        pass

    def _extract_markdown_code_blocks(self, markdown_text: str) -> List[CodeBlock]:
        pattern = re.compile(rf"```(?:\s*({self._supported_languages_regex}))\n([\s\S]*?)```", re.IGNORECASE)
        matches = pattern.findall(markdown_text)
        code_blocks: List[CodeBlock] = []
        for match in matches:
            language = match[0].strip() if match[0] else ""
            code_content = match[1]
            code_blocks.append(CodeBlock(code=code_content, language=language))
        return code_blocks

    def _to_config(self) -> CodeExecutorAgentConfig:
        if self._approval_func is not None:
            raise ValueError(
                "Cannot serialize CodeExecutorAgent with approval_func set. The approval function is not serializable."
            )

        return CodeExecutorAgentConfig(
            name=self.name,
            model_client=(self._model_client.dump_component() if self._model_client is not None else None),
            code_executor=self._code_executor.dump_component(),
            description=self.description,
            sources=list(self._sources) if self._sources is not None else None,
            system_message=(
                self._system_messages[0].content
                if self._system_messages and isinstance(self._system_messages[0].content, str)
                else None
            ),
            model_client_stream=self._model_client_stream,
            model_context=self._model_context.dump_component(),
            supported_languages=self._supported_languages,
        )

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Don't serialize agents that hold callbacks: rebuild the agent from your own config and re-attach approval_func after loading.
  2. Remove approval_func before calling dump_component() and register it again on the reconstructed instance.
  3. Store the approval decision as serializable state (e.g. allowlist rules) instead of a closure.

Example fix

// before
agent = CodeExecutorAgent(name="coder", code_executor=exec_, approval_func=my_func)
config = agent.dump_component()  # raises

// after
agent = CodeExecutorAgent(name="coder", code_executor=exec_)
config = agent.dump_component()  # ok
# rebuild later and re-attach the callback
agent2 = CodeExecutorAgent.load_component(config)
agent2._approval_func = my_func  # or re-construct with approval_func
Defensive patterns

Strategy: validation

Validate before calling

def can_serialize(agent) -> bool:
    return getattr(agent, "_approval_func", None) is None

if can_serialize(agent):
    config = agent.dump_component()
else:
    # persist executor/model config only; rebuild agent + reattach callback later
    config = None

Try / catch

try:
    config = agent.dump_component()
except ValueError as e:
    if "not serializable" in str(e):
        # rebuild without the callback, reattach on load
        ...
    raise

Prevention

When it happens

Trigger: Calling agent.dump_component() (or a workflow that serializes agents) on a CodeExecutorAgent constructed with approval_func=some_callable.

Common situations: Human-in-the-loop setups with code approval callbacks combined with checkpointing/persistence frameworks that dump agent components; attempting save/load round-trips of an agent holding closures.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/0b11adc9bbc9f2bd. Report an issue: GitHub.