Skip to content

TypeError in LoadSkillTool.run_async after session rewind: 'NoneType' object is not iterable #5193

Closed

Description

@SAMFVH

Bug Report

Description

LoadSkillTool.run_async crashes with TypeError: 'NoneType' object is not iterable after a session rewind when the skills feature is enabled.

Steps to Reproduce

  1. Enable the SKILL_TOOLSET experimental feature
  2. Run an agent session that activates a skill (populating _adk_activated_skill_{agent_name} in state)
  3. Rewind the session to a point before the skill was activated
  4. Continue the session and trigger a load_skill tool call

Root Cause

Runner._compute_state_delta_for_rewind (runners.py:716) sets state keys to None to mark them for deletion when they were added after the rewind point:

# runners.py:715-716
if key not in state_at_rewind_point:
    rewind_state_delta[key] = None

This sets _adk_activated_skill_{agent_name} to None. Later, LoadSkillTool.run_async does:

# skill_toolset.py:155
activated_skills = list(tool_context.state.get(state_key, []))

Since the key exists with value None, dict.get() returns None (not the default []), and list(None) raises TypeError.

Stack Trace

File ".../google/adk/tools/skill_toolset.py", line 155, in run_async
    activated_skills = list(tool_context.state.get(state_key, []))
TypeError: 'NoneType' object is not iterable

Suggested Fix

# skill_toolset.py:155
activated_skills = list(tool_context.state.get(state_key) or [])

This handles both missing keys and explicit None values. The same pattern should be applied to _resolve_additional_tools_from_state (line 742) for consistency, even though it currently doesn't crash due to the if not activated_skills guard on line 744.

Version

google-adk 1.3.0

Activity

  1. added
    tools[Component] This issue is related to tools
    on Apr 7, 2026
  2. added theissue type on Apr 7, 2026
  3. added a commit that references this issue on Apr 7, 2026
    cb5d1f8
  4. enjoykumawat commented on Apr 7, 2026

    @enjoykumawat
    Contributor

    I'd like to work on this. Adding a None guard before iterating in LoadSkillTool.run_async. Will submit a PR shortly.

  5. surajksharma07 commented on Apr 7, 2026

    @surajksharma07
    Collaborator

    @SAMFVH The rewind path sets adk_activated_skill{agent_name} to None as a deletion marker, and dict.get(key, default) only falls back to the default when the key is absent — not when it's explicitly None — so list(None) blows up.

    As a quick workaround, try swapping line 155 in skill_toolset.py from state.get(state_key, []) to state.get(state_key) or [] and see if that clears the crash on your end.

    Commit cb5d1f8 is already heading in this direction, but it'd be great if you could test it thoroughly on your setup.

  6. SAMFVH commented on Apr 7, 2026

    @SAMFVH
    Author

    We ran into this in production. Our workaround patches all 3 crash sites from our side:

    1. LoadSkillTool.run_async (line 155) — subclassed LoadSkillTool to normalize None → [] in state before calling super().run_async()
    2. SkillToolset._resolve_additional_tools_from_state (line 742) — overrode in our SkillToolset subclass to normalize via the underlying session.state (since ReadonlyContext.state is a MappingProxyType)
    3. Our own activate_skill_for_step that also reads the same state key — switched from list(state.get(key, [])) to list(raw) if raw is not None else []

    Happy to see this fixed upstream so we can drop the workarounds. The suggested state.get(key) or [] would work for all 3 sites.

  7. surajksharma07 commented on Apr 9, 2026

    @surajksharma07
    Collaborator

    @SAMFVH — thanks for the detailed production breakdown, really helpful to have that level of context!

    PR #5204 applies the or [] guard to both sites in skill_toolset.py (line 155 and line 742), which should cover crash sites 1 and 2 on your end.
    Site 3 is in your own activate_skill_for_step code, so that one stays with you.

    Keep an eye on #5204 for the merge — once it lands you should be able to drop the subclass workarounds entirely!

    Team is looking more into it.

  8. surajksharma07 commented on Apr 15, 2026

    @surajksharma07
    Collaborator

    @xuanyang15 Please have a look into it once.

  9. xuanyang15 commented on Apr 16, 2026

    @xuanyang15
    Collaborator

    PR merged in a977aa3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

needs review[Status] The PR/issue is awaiting review from the maintainertools[Component] This issue is related to tools

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions