{"record":{"id":"5da4e8a00df09fc9","repo":"microsoft/autogen","slug":"the-string-must-contain-exactly-one-function","errorCode":null,"errorMessage":"The string must contain exactly one function","messagePattern":"The string must contain exactly one function","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-core/src/autogen_core/code_executor/_func_with_reqs.py","lineNumber":121,"sourceCode":"        self.global_imports = global_imports\n\n        module_name = \"func_module\"\n        loader = _StringLoader(func)\n        spec = spec_from_loader(module_name, loader)\n        if spec is None:\n            raise ValueError(\"Could not create spec\")\n        module = module_from_spec(spec)\n        if spec.loader is None:\n            raise ValueError(\"Could not create loader\")\n\n        try:\n            spec.loader.exec_module(module)\n        except Exception as e:\n            raise ValueError(f\"Could not compile function: {e}\") from e\n\n        functions = inspect.getmembers(module, inspect.isfunction)\n        if len(functions) != 1:\n            raise ValueError(\"The string must contain exactly one function\")\n\n        self._func_name, self.compiled_func = functions[0]\n\n    def __call__(self, *args: Any, **kwargs: Any) -> None:\n        raise NotImplementedError(\"String based function with requirement objects are not directly callable\")\n\n\n@dataclass\nclass FunctionWithRequirements(Generic[T, P]):\n    func: Callable[P, T]\n    python_packages: Sequence[str] = field(default_factory=list)\n    global_imports: Sequence[Import] = field(default_factory=list)\n\n    @classmethod\n    def from_callable(\n        cls, func: Callable[P, T], python_packages: Sequence[str] = [], global_imports: Sequence[Import] = []\n    ) -> FunctionWithRequirements[T, P]:\n        return cls(python_packages=python_packages, global_imports=global_imports, func=func)","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-core/src/autogen_core/code_executor/_func_with_reqs.py#L103-L139","documentation":"After executing the module, FunctionWithRequirementsStr enumerates module-level functions with inspect.getmembers(..., inspect.isfunction) and requires exactly one. Zero functions (only statements/classes), two or more defs (e.g. a helper function), or a string where the target is a lambda assigned to a name all break the count. Imports do not count: an `import`ed function is a module attribute only if it is a plain function, which can also skew the count.","triggerScenarios":"Passing \"x = 1\" (no def), a string with \"def helper(): ...\" plus \"def main(): ...\" (two functions), or a string that does `from math import sqrt` (sqrt is a builtin, not isfunction, so safe) versus `from mymod import util` where util is a Python function (counts as a second function).","commonSituations":"Refactoring a single function into main + helpers without merging them into one def; embedding decorators defined in the same string; copy-pasting a multi-function module into the func parameter.","solutions":["Ensure the string defines exactly one top-level `def` and no other function definitions.","Inline helpers as nested functions inside the single def.","If multiple functions are genuinely needed, wrap them in a class or pass each as its own FunctionWithRequirementsStr."],"exampleFix":"# before (two functions)\nf = FunctionWithRequirementsStr(\"def helper(v): return v * 2\\ndef main(x): return helper(x) + 1\")\n\n# after (single function, helper nested)\nf = FunctionWithRequirementsStr(\n    \"def main(x):\\n    def helper(v): return v * 2\\n    return helper(x) + 1\"\n)","handlingStrategy":"validation","validationCode":"import ast\n\ndef defines_exactly_one_function(source: str) -> bool:\n    tree = ast.parse(source)\n    return sum(isinstance(n, ast.FunctionDef) for n in tree.body) == 1","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the source string to a single top-level def; nest helpers inside it.","Validate with ast before constructing so errors point at real line numbers.","Remember imported plain-Python functions also count toward inspect.getmembers' tally."],"tags":["python","autogen-core","code-executor","dynamic-code","validation"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}