Skip to content

[Bug][Python] Silent config-reconstruction fallback in Action deserialization makes failures very hard to debug #920

Description

@alnzng

Search before asking

  • I searched in the issues and found nothing similar.

Description

What I was testing

A ReActAgent with both tools and an output_schema (FlinkSqlJobProfile). The schema class was importable on the driver but not on the worker (a packaging mistake on my side).

Symptom

The job failed at runtime pointing at chat_model_action.py with a misleading AttributeError:

pemja.core.PythonException: <class 'AttributeError'>: 'list' object has no attribute 'model_dump'
    at .../flink_agents/plan/actions/chat_model_action._save_tool_request_event_context
(chat_model_action.py:115)
    at .../flink_agents/plan/actions/chat_model_action._handle_tool_calls (chat_model_action.py:237)
    at .../flink_agents/plan/actions/chat_model_action.chat (chat_model_action.py:379)
    at .../flink_agents/plan/actions/chat_model_action._process_chat_request (chat_model_action.py:410)
    at .../flink_agents/plan/actions/chat_model_action.process_chat_request_or_tool_response
(chat_model_action.py:470)
    at pemja.core.PythonInterpreter.invoke(PythonInterpreter.java:92)
    at org.apache.flink.agents.runtime.operator.ActionExecutionOperator.processActionTaskForKey(ActionExecutionOp
erator.java:375)

Nothing here points at the real problem.

Actual root cause

Action.__custom_deserialize (plan/actions/action.py) reconstructs [module, class, value] config values
inside a try/except that silently swallows any failure and keeps the raw value:

for name, value in config.items():
    try:
        module = importlib.import_module(value[0])
        clazz = getattr(module, value[1])
        self["config"][name] = clazz.model_validate(value[2])
    except Exception:          # <-- swallows the real error
        self["config"][name] = value

My output_schema class wasn't importable on the worker → reconstruction raised ModuleNotFoundError
swallowed → output_schema stayed a raw list → later _save_tool_request_event_context called .model_dump() on that list → the misleading AttributeError above.

What the error should have looked like

Making the branch fail fast instead of swallowing gave the true cause and location, at plan-load before any
record was processed:

pemja.core.PythonException: <class 'ModuleNotFoundError'>: No module named 'streamingjobprofileagent'
    at <frozen importlib._bootstrap>:1360 (_find_and_load)
    at /export/apps/python/3.12.6/lib/python3.12/importlib/__init__.import_module (__init__.py:90)
    at .../flink_agents/api/agents/types.__custom_deserialize (types.py:65)
    at .../pydantic/main.model_validate (main.py:732)
    at .../flink_agents/plan/actions/action.__custom_deserialize (action.py:94)
    at .../flink_agents/plan/actions/action.__init__ (action.py:107)
    at .../flink_agents/runtime/flink_runner_context.create_flink_runner_context (flink_runner_context.py:773)
    at pemja.core.PythonInterpreter.invoke(PythonInterpreter.java:94)
    at org.apache.flink.agents.runtime.python.utils.PythonActionExecutor.open(PythonActionExecutor.java:108)
    at org.apache.flink.agents.runtime.operator.ActionExecutionOperator.open(ActionExecutionOperator.java:172)

Real error (ModuleNotFoundError), real location (action.py / types.py), failing at operator open()
instead of a downstream AttributeError in an unrelated module.

How to reproduce

  1. Define a ReActAgent with tools=[...] and output_schema=SomeModel, where SomeModel is importable when the plan is built (driver) but not importable in the worker process.
  2. Run the agent so the LLM issues a tool call.
  3. The worker crashes with 'list' object has no attribute 'model_dump' from chat_model_action.py, with nothing indicating the real ModuleNotFoundError raised during config deserialization in action.py.

Version and environment

  • flink-agents: 0.3.0
  • Python: 3.12
  • Flink: 2.2.x, deployed on Kubernetes

Are you willing to submit a PR?

  • I'm willing to submit a PR!

Metadata

Metadata

Assignees

Labels

bug[Issue Type] Something isn't working as expected.fixVersion/0.3.1The feature or bug should be implemented/fixed in the 0.3.1 version.priority/majorDefault priority of the PR or issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions