actions icon indicating copy to clipboard operation
actions copied to clipboard

Action server fails to start under sema4ai-actions 1.4.2 due to docstring_parser import error (DocstringYields)

Open joshyorko opened this issue 3 months ago • 2 comments

Summary

Upgrading sema4ai-actions from 1.4.1 to 1.4.2 in package.yaml causes the action server to fail to start during action collection. The failure originates in docstring parsing/linting: the environment raises an ImportError when docstring_parser.common is expected to expose DocstringYields but does not.

This does not occur with sema4ai-actions=1.4.1 (downgrading to 1.4.1 is an immediate workaround).

Reproduction (minimal)

  1. In package.yaml set:
pypi:
  - sema4ai-actions=1.4.2
  # ... other deps
  1. Run the action server from the repo root:
action-server start

Observed behavior / error

The server fails during action import/collection with a traceback similar to:

ImportError: cannot import name 'DocstringYields' from 'docstring_parser.common' (/opt/.../site-packages/docstring_parser/common.py)
...
RuntimeError: It was not possible to list the actions.
...
Error when importing module 'src.linkedin.linkedin-actions' at location '.../src/linkedin/linkedin-actions.py'

Key excerpt from the log we observed inside our environment:

Error calling: <function _ActionsArgDispatcher._register_lint.<locals>.on_func_found at 0x...>.
Traceback (most recent call last):
  File "/opt/.../site-packages/sema4ai/actions/_callback.py", line 48, in __call__
    c(*args, **kwargs)
  File "/opt/.../site-packages/sema4ai/actions/_args_dispatcher.py", line 281, in on_func_found
    errors = list(
             ^^^^^
  File "/opt/.../site-packages/sema4ai/actions/_args_dispatcher.py", line 283, in <genexpr>
    for x in _lint_action.iter_lint_errors(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/.../site-packages/sema4ai/actions/_lint_action.py", line 435, in iter_lint_errors
    yield from _check_docstring_contents(pm, node, docstring, kind)
  File "/opt/.../site-packages/sema4ai/actions/_lint_action.py", line 274, in _check_docstring_contents
    import docstring_parser
  File "/opt/.../site-packages/docstring_parser/__init__.py", line 14, in <module>
    from .parser import compose, parse, parse_from_object
  File "/opt/.../site-packages/docstring_parser/parser.py", line 6, in <module>
    from docstring_parser import epydoc, google, numpydoc, rest
  File "/opt/.../site-packages/docstring_parser/numpydoc.py", line 12, in <module>
    from .common import (
ImportError: cannot import name 'DocstringYields' from 'docstring_parser.common' (/opt/.../site-packages/docstring_parser/common.py)

Why we think this is a problem with the release

  • The issue only appears when using sema4ai-actions=1.4.2 and not with 1.4.1.
  • The error points to docstring_parser internals; likely either a transitive dependency version change, or a change in sema4ai-actions that expects a newer docstring_parser API than what is present in the environment.
  • The action package import path fails while running the docstring lint step inside your action-collection flow, indicating a docstring parsing incompatibility.

Immediate workaround

  • Pin sema4ai-actions=1.4.1 in package.yaml. That restores action-server startup in our environment.

Suggested fixes for maintainers

  1. Audit the sema4ai-actions 1.4.2 dependency pins (direct or transitive) for docstring_parser and ensure it pins a version that exposes DocstringYields or adapt the docstring lint code to work with the currently installed docstring_parser versions.

  2. Consider adding a try/except fallback in the docstring linting code to gracefully skip/ignore the yields-related checks when DocstringYields is unavailable (and log a clear message), rather than raising ImportError and preventing action loading.

  3. Add a minimal reproducible test or CI job that runs action collection against a repo with several typical action docstrings; this would detect breakages caused by docstring_parser API changes earlier.

Information from our environment (for context)

  • Repo: linkedin-easy-apply
  • package.yaml (relevant lines):
pypi:
  - sema4ai-actions=1.4.2  # triggers the error
  - robocorp-browser=2.3.5
  - python-dotenv=1.1.1
  - beautifulsoup4=4.13.5
  - pandas=2.3.2
  - mindsdb_sdk=3.4.6
  - SQLAlchemy=2.0.43
  - psycopg2-binary=2.9.10
  • Python: 3.12.x (the action-server runtime used python3.12 in our setup)
  • Observed behavior on action-server start (command prints earlier stacktrace and aborts)

Request

Could you please:

  • Investigate if sema4ai-actions 1.4.2 introduced a changed dependency or internal usage of docstring_parser that requires DocstringYields? If so, pin a compatible docstring_parser version or add a fallback.
  • If you prefer, I can open a PR that clamps the docstring_parser version or makes the lint code resilient — tell me which approach you'd prefer.

Thanks — this is blocking action server startup for users who build with sema4ai-actions 1.4.2; downgrading to 1.4.1 is an immediate workaround.

FWIW not sure if this due to me being on action-server v2.14.1binary.

joshyorko avatar Aug 29 '25 12:08 joshyorko

Additional findings after digging into the 1.4.2 code and dependencies:

  • In 1.4.2, actions/pyproject.toml pins docstring_parser_fork = "^0.0.5". At runtime, this fork is imported as docstring_parser.
  • Your code paths (_lint_action.py, _action.py) import docstring_parser at top-level and call parse(...). I don’t see any direct usage of docstring_parser.common or DocstringYields in your repo.
  • The ImportError we hit (cannot import name 'DocstringYields' from 'docstring_parser.common') originates inside the installed docstring_parser package itself when it tries to from .common import (...) DocstringYields ... (see the stack in numpydoc.py). This suggests the forked package version in our environment either doesn’t ship or doesn’t re-export DocstringYields from common.py, while another submodule still expects it.

Hypothesis

  • The docstring_parser_fork build that 1.4.2 resolves to is internally inconsistent: one module expects DocstringYields in common, while common.py in that build doesn’t define or export it. The upstream issue requesting DocstringYields support exists (rr-/docstring_parser#78), which aligns with the symbol name.

Recommendations

  • Either: (a) bump to a fork version that contains a consistent DocstringYields implementation across common.py and importer modules, or (b) pin to an upstream docstring_parser version (e.g., 0.16/0.17) that matches your expectations, or (c) vendor a minimal compatibility shim that defines DocstringYields = DocstringReturns when missing.
  • As a safety net, catch ImportError around the yields/returns checks in _lint_action._check_docstring_contents and degrade gracefully (log a warning) so action discovery isn’t blocked by a parser internals mismatch.

Workaround confirmation

  • Confirmed again that pinning back to sema4ai-actions=1.4.1 avoids the issue entirely in our project.

If it helps, I’m happy to test a pre-release (or provide full site-packages file listings for the forked parser) to validate the fix.

joshyorko avatar Aug 29 '25 12:08 joshyorko

also checked with action-server version v2.4.2 binary to confirm:


(.venv) ➜  linkedin-easy-apply git:(main) ✗ action-server start
PyInstaller/loader/pyimod02_importers.py:450: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
RCC not available at: /home/kdlocpanda/.sema4ai/bin/action-server/internal/2.14.2/_internal/sema4ai/action_server/bin/rcc-20.1.1. Downloading.
Downloading 'https://cdn.sema4.ai/rcc/releases/v20.1.1/linux64/rcc' to '/home/kdlocpanda/.sema4ai/bin/action-server/internal/2.14.2/_internal/sema4ai/action_server/bin/rcc-20.1.1'
Download attempt #1
File successfully downloaded

  ⚡️ Starting Action Server... v2.14.2

Using datadir: /home/kdlocpanda/.sema4ai/action-server/linkedin-easy-apply_f9642bc3
Logs may be found at: /home/kdlocpanda/.sema4ai/action-server/linkedin-easy-apply_f9642bc3/server_log.txt.
Database file does not exist. Creating it at: /home/kdlocpanda/.sema4ai/action-server/linkedin-easy-apply_f9642bc3/server.db
Action package seems ok. Bootstrapping RCC environment (please wait, this can take a long time).
Python interpreter path: /opt/sema4ai/ht/2a6fe41_a78733b_d5163427/bin/python3
Traceback (most recent call last):
  File "action_server/__main__.py", line 18, in <module>
  File "action_server/cli.py", line 62, in main
    retcode = _main_retcode(args)
              ^^^^^^^^^^^^^^^^^^^
  File "action_server/_cli_impl.py", line 759, in _main_retcode
    return _command_requiring_datadir(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "action_server/_cli_impl.py", line 925, in _command_requiring_datadir
    code = _import_actions(
           ^^^^^^^^^^^^^^^^
  File "action_server/_cli_impl.py", line 583, in _import_actions
    _actions_import.import_action_package(
  File "action_server/_actions_import.py", line 192, in import_action_package
    _add_actions_to_db(
  File "action_server/_actions_import.py", line 315, in _add_actions_to_db
    raise RuntimeError(
RuntimeError: It was not possible to list the actions.
cmdline: /opt/sema4ai/ht/2a6fe41_a78733b_d5163427/bin/python3 -c "
try:
    from sema4ai.actions import cli
except:
    from robocorp.actions import cli

cli.main([\"metadata\"])
"
cwd: /home/kdlocpanda/syncthing_/config/second_brain/Areas/RPA/action_servers/linkedin-easy-apply
stdout:
stderr:/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/mindsdb_sdk/utils/objects_collection.py:12: SyntaxWarning: invalid escape sequence '\w'
  items = [i for i in items if re.match('^(?![0-9])\w+$', i)]
[DB] MindsDB client imported successfully
Error calling: <function _ActionsArgDispatcher._register_lint.<locals>.on_func_found at 0x799ac724b560>.
Traceback (most recent call last):
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_callback.py", line 48, in __call__
    c(*args, **kwargs)
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_args_dispatcher.py", line 281, in on_func_found
    errors = list(
             ^^^^^
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_args_dispatcher.py", line 283, in <genexpr>
    for x in _lint_action.iter_lint_errors(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_lint_action.py", line 435, in iter_lint_errors
    yield from _check_docstring_contents(pm, node, docstring, kind)
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_lint_action.py", line 274, in _check_docstring_contents
    import docstring_parser
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/docstring_parser/__init__.py", line 14, in <module>
    from .parser import compose, parse, parse_from_object
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/docstring_parser/parser.py", line 6, in <module>
    from docstring_parser import epydoc, google, numpydoc, rest
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/docstring_parser/numpydoc.py", line 12, in <module>
    from .common import (
ImportError: cannot import name 'DocstringYields' from 'docstring_parser.common' (/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/docstring_parser/common.py)
Error when importing module 'src.linkedin.linkedin-actions'
  at location '/home/kdlocpanda/syncthing_/config/second_brain/Areas/RPA/action_servers/linkedin-easy-apply/src/linkedin/linkedin-actions.py'
  (with root: '/home/kdlocpanda/syncthing_/config/second_brain/Areas/RPA/action_servers/linkedin-easy-apply').
Traceback (most recent call last):
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_commands.py", line 97, in metadata
    for action in collect_actions(pm, p, glob=glob):
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_collect_actions.py", line 494, in collect_actions
    import_path(path_with_action, root=root)
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_collect_actions.py", line 374, in import_path
    spec.loader.exec_module(mod)  # type: ignore[union-attr]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap_external>", line 999, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/home/kdlocpanda/syncthing_/config/second_brain/Areas/RPA/action_servers/linkedin-easy-apply/src/linkedin/linkedin-actions.py", line 108, in <module>
    @action
     ^^^^^^
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/__init__.py", line 130, in action
    return decorator(args[0], **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/__init__.py", line 118, in decorator
    _hooks.on_action_func_found(
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_callback.py", line 48, in __call__
    c(*args, **kwargs)
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_args_dispatcher.py", line 281, in on_func_found
    errors = list(
             ^^^^^
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_args_dispatcher.py", line 283, in <genexpr>
    for x in _lint_action.iter_lint_errors(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_lint_action.py", line 435, in iter_lint_errors
    yield from _check_docstring_contents(pm, node, docstring, kind)
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/sema4ai/actions/_lint_action.py", line 274, in _check_docstring_contents
    import docstring_parser
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/docstring_parser/__init__.py", line 14, in <module>
    from .parser import compose, parse, parse_from_object
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/docstring_parser/parser.py", line 6, in <module>
    from docstring_parser import epydoc, google, numpydoc, rest
  File "/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/docstring_parser/numpydoc.py", line 12, in <module>
    from .common import (
ImportError: cannot import name 'DocstringYields' from 'docstring_parser.common' (/opt/sema4ai/ht/2a6fe41_a78733b_d5163427/lib/python3.12/site-packages/docstring_parser/common.py)

Error executing action-server: exit status 1

joshyorko avatar Aug 29 '25 12:08 joshyorko