Skip to content

CodeAct executor crashes with TypeError: object of type 'NoneType' has no len() because ui_state was never stored before execution #250

Description

@mbjd05

Problem

During CodeAct execution, the script pane received ui_state=None, so any code block iterating over ui_state (e.g., for i in range(len(ui_state))) crashes with TypeError: object of type 'NoneType' has no len() (droidrun/agent/codeact/codeact_agent.py:422). The executor reads the snapshot from ctx.store.get("ui_state"), but handle_llm_input never persisted the latest accessibility tree to the store, only to events.

  • Minimal Repro: Run a CodeAct agent by running droidrun with the following prompt (the same one with which I initially encountered this error):

    open the webbrowser then go to options -> history and produce a file with all page titles and their urls of pages visited.

    The generated code will likely attempt something like for i in range(len(ui_state)) immediately after observing the UI. The executor fails with the quoted TypeError even if valid data is present in events.

Proposed Fix

After fetching device state and updating shared_state, persist the a11y_tree (the UI accessibility dump) into the workflow store:

await ctx.store.set("ui_state", a11y_tree) 

Add this immediately after populating shared_state in handle_llm_input (line 310).

This mirrors how screenshots are handled (by persisting them to the workflow store at line 295) and ensures ctx.store.get("ui_state") in execute_code always returns the latest list, preventing NoneType crashes. It maintains the contract between perception and execution steps so code can safely iterate the UI snapshot.

Summary

CodeActAgent.handle_llm_input should store the freshly-fetched a11y_tree in the workflow store right after updating shared_state. This ensures that execute_code always receives a proper UI state, fixing the dataflow bug that led to the TypeError.

Activity

  1. johnmalek312 commented on Jan 10, 2026

    @johnmalek312
    Contributor

    The ui state isnt meant to be iterated over programmatically, its given to codeact in the prompt. Ask it in the prompt not to do that.

  2. added a commit that references this issue on Mar 3, 2026
    da07e1d
  3. RasulOs commented on Aug 4, 2026

    @RasulOs
    Collaborator

    Claude:
    Good report, but this code path no longer exists: CodeActAgent and the exec-based executor were removed in 1fee3be (March 2026), and direct mode is now FastAgent, which emits XML tool calls instead of generating Python — so no generated code touches ui_state anymore. That unfortunately also strands PR #275, which targets the deleted file.

    Closing as obsolete — thanks again for the well-isolated repro.

  4. moved this from 📨 Inbox to ✅ Done in Bounty Boardon Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions