Search before asking
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
- 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.
- Run the agent so the LLM issues a tool call.
- 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?
Search before asking
Description
What I was testing
A
ReActAgentwith bothtoolsand anoutput_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.pywith a misleadingAttributeError:Nothing here points at the real problem.
Actual root cause
Action.__custom_deserialize(plan/actions/action.py) reconstructs[module, class, value]config valuesinside a
try/exceptthat silently swallows any failure and keeps the raw value:My
output_schemaclass wasn't importable on the worker → reconstruction raisedModuleNotFoundError→swallowed →
output_schemastayed a rawlist→ later_save_tool_request_event_contextcalled.model_dump()on that list → the misleadingAttributeErrorabove.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:
Real error (
ModuleNotFoundError), real location (action.py/types.py), failing at operatoropen()—instead of a downstream
AttributeErrorin an unrelated module.How to reproduce
ReActAgentwithtools=[...]andoutput_schema=SomeModel, whereSomeModelis importable when the plan is built (driver) but not importable in the worker process.'list' object has no attribute 'model_dump'fromchat_model_action.py, with nothing indicating the realModuleNotFoundErrorraised during config deserialization inaction.py.Version and environment
Are you willing to submit a PR?