Skip to content

adk web command fails with "UnboundLocalError: cannot access local variable 'ApiServer' where it is not associated with a value" #5782

Closed

Description

@gabrielle-lau

🔴 Required Information

Describe the Bug:
ADK 2.0.0 fails to launch the ADK Dev UI with flags, specifically this command:

adk web \
--allow_origins "regex:https://.*\.cloudshell\.dev" \
--otel_to_cloud \
--reload_agents

Steps to Reproduce:
Follow the "Get Started with Agent Development Kit (ADK)" course lab, task 3 step 3 fails.

Lab: https://www.skills.google/course_templates/1382/labs/583500

  1. Install google-adk-2.0.0 fastapi-0.136.1 by running python3 -m pip install google-adk[otel-gcp] -r adk_project/requirements.txt
  2. Run
adk web \
--allow_origins "regex:https://.*\.cloudshell\.dev" \
--otel_to_cloud \
--reload_agents
  1. Error:
  File "/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/cli/fast_api.py", line 582, in get_fast_api_app
    def setup_observer(observer: Observer, adk_web_server: ApiServer):
                                                           ^^^^^^^^^
UnboundLocalError: cannot access local variable 'ApiServer' where it is not associated with a value

Expected Behavior:
The localhost server should start

INFO:     Started server process [2434]
INFO:     Waiting for application startup.
+-------------------------------------------------------+
| ADK Web Server started                                |
|                                                       |
| For local testing, access at http://localhost:8000.   |
+-------------------------------------------------------+

INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Observed Behavior:
Localhost server fails to start. Commands and resulting stacktrace:

Successfully installed aiosqlite-0.22.1 annotated-doc-0.0.4 authlib-1.7.2 fastapi-0.136.1 google-adk-2.0.0 google-genai-1.75.0 graphviz-0.21 joblib-1.5.3 joserfc-1.6.5 opentelemetry-instrumentation-0.61b0 opentelemetry-instrumentation-google-genai-0.7b1 opentelemetry-util-genai-0.3b0 pyopenssl-26.2.0 python-dotenv-1.2.2 scikit-learn-1.8.0 scipy-1.17.1 starlette-0.52.1 threadpoolctl-3.6.0 tzlocal-5.3.1 uvicorn-0.47.0 watchdog-6.0.0 websockets-15.0.1 wrapt-1.17.3
student_04_053c77e90b9f@cloudshell:~ (qwiklabs-gcp-03-856a0320c159)$ cd ~/adk_project
student_04_053c77e90b9f@cloudshell:~/adk_project (qwiklabs-gcp-03-856a0320c159)$ cat << EOF > my_google_search_agent/.env
GOOGLE_GENAI_USE_VERTEXAI=TRUE
GOOGLE_CLOUD_PROJECT=qwiklabs-gcp-03-856a0320c159
GOOGLE_CLOUD_LOCATION=global
MODEL=gemini-3-flash-preview
OTEL_SERVICE_NAME=adk-agent
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
EOF
student_04_053c77e90b9f@cloudshell:~/adk_project (qwiklabs-gcp-03-856a0320c159)$ cd ~/adk_project
student_04_053c77e90b9f@cloudshell:~/adk_project (qwiklabs-gcp-03-856a0320c159)$ adk web \
--allow_origins "regex:https://.*\.cloudshell\.dev" \
--otel_to_cloud \
--reload_agents
2026-05-21 10:11:32,275 - INFO - service_factory.py:265 - Using in-memory memory service
2026-05-21 10:11:32,276 - INFO - local_storage.py:84 - Using per-agent session storage rooted at /home/student_04_053c77e90b9f/adk_project
2026-05-21 10:11:32,277 - INFO - local_storage.py:110 - Using file artifact service at /home/student_04_053c77e90b9f/adk_project/.adk/artifacts
/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/cli/fast_api.py:514: UserWarning: [EXPERIMENTAL] InMemoryCredentialService: This feature is experimental and may change or be removed in future versions without notice. It may introduce breaking changes at any time.
  credential_service = InMemoryCredentialService()
/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/auth/credential_service/in_memory_credential_service.py:33: UserWarning: [EXPERIMENTAL] BaseCredentialService: This feature is experimental and may change or be removed in future versions without notice. It may introduce breaking changes at any time.
  super().__init__()
Traceback (most recent call last):
  File "/home/student_04_053c77e90b9f/.local/bin/adk", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/click/core.py", line 1485, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/click/core.py", line 1406, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/click/core.py", line 1873, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/click/core.py", line 1269, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/click/core.py", line 824, in invoke
    return callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/cli/cli_tools_click.py", line 124, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/click/decorators.py", line 34, in new_func
    return f(get_current_context(), *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/cli/cli_tools_click.py", line 1710, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/cli/cli_tools_click.py", line 1552, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/cli/cli_tools_click.py", line 597, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/cli/cli_tools_click.py", line 1811, in cli_web
    app = get_fast_api_app(
          ^^^^^^^^^^^^^^^^^
  File "/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/cli/fast_api.py", line 582, in get_fast_api_app
    def setup_observer(observer: Observer, adk_web_server: ApiServer):
                                                           ^^^^^^^^^
UnboundLocalError: cannot access local variable 'ApiServer' where it is not associated with a value

Environment Details:

  • ADK Library Version (pip show google-adk): google-adk-2.0.0
  • Desktop OS:** [e.g., macOS, Linux, Windows]: Linux (GCP Cloud Shell)
  • Python Version (python -V): python3.12

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: gemini-3-flash-preview

🟡 Optional Information

Providing this information greatly speeds up the resolution process.

Regression:
Used to work in ADK 1.34.0
Workaround: pip uninstall google-adk, then install previous version:

python3 -m pip install google-adk[otel-gcp]==1.34.0

Then run the same command:

student_04_053c77e90b9f@cloudshell:~/adk_project (qwiklabs-gcp-03-856a0320c159)$ adk web \
--allow_origins "regex:https://.*\.cloudshell\.dev" \
--otel_to_cloud \
--reload_agents
2026-05-21 10:29:19,463 - INFO - service_factory.py:265 - Using in-memory memory service
2026-05-21 10:29:19,464 - INFO - local_storage.py:84 - Using per-agent session storage rooted at /home/student_04_053c77e90b9f/adk_project
2026-05-21 10:29:19,465 - INFO - local_storage.py:110 - Using file artifact service at /home/student_04_053c77e90b9f/adk_project/.adk/artifacts
/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/cli/fast_api.py:208: UserWarning: [EXPERIMENTAL] InMemoryCredentialService: This feature is experimental and may change or be removed in future versions without notice. It may introduce breaking changes at any time.
  credential_service = InMemoryCredentialService()
/home/student_04_053c77e90b9f/.local/lib/python3.12/site-packages/google/adk/auth/credential_service/in_memory_credential_service.py:33: UserWarning: [EXPERIMENTAL] BaseCredentialService: This feature is experimental and may change or be removed in future versions without notice. It may introduce breaking changes at any time.
  super().__init__()
INFO:     Started server process [2261]
INFO:     Waiting for application startup.

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://127.0.0.1:8000.                         |
+-----------------------------------------------------------------------------+

INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

How often has this issue occurred?:
Since yesterday 2026-05-21

  • Always (100%)

Activity

  1. added
    web[Component] This issue will be transferred to adk-web
    on May 21, 2026
  2. added theissue type on May 21, 2026
  3. surajksharma07 commented on May 21, 2026

    @surajksharma07
    Collaborator

    @gabrielle-lau in fast_api.py (v2.0.0), from .api_server import ApiServer appears inside two conditional branches within get_fast_api_app() (lines 529 and 533), which causes Python to treat ApiServer as a local variable for the entire function.

    When web=True and DevServer imports successfully, neither branch executes, so ApiServer is local but never assigned — and the type annotation on setup_observer at line 582 (only reached with --reload_agents) triggers the UnboundLocalError.

    The fix is straightforward: remove those two redundant local imports since ApiServer is already imported at module level on line 42. Deleting from .api_server import ApiServer at lines 529 and 533 and letting ServerClass = ApiServer use the module-level name directly should do it.

    Could you verify this patch resolves it on your end ?

  4. added
    request clarification[Status] The maintainer need clarification or more information from the author
    v2Affects only 2.0 version
    on May 21, 2026
  5. gabrielle-lau commented on May 21, 2026

    @gabrielle-lau
    Author

    Thanks for getting back. I later came across this issue with the patch you mentioned that worked for someone else:
    #5765

    IIUC it's an ADK regression. While users could patch locally, to have a proper fix, could we merge a fix (there's a pending PR), and push a new ADK release please?

  6. surajksharma07 commented on May 21, 2026

    @surajksharma07
    Collaborator

    @gabrielle-lau Yes, #5765 is the same root cause and PR #5769 ("fix: avoid ApiServer scope shadowing in web reload") applies exactly the 2-line deletion we described — once that merges, a patch release will resolve this cleanly without any local edits needed.

    In the meantime, the local patch (removing the redundant from .api_server import ApiServer at lines 529 and 533 in fast_api.py) is safe and behaviorally identical to the PR.

    Linking this to #5765 and flagging #5769 for priority.

    Team is looking more into it.
    Thanks!

  7. sasha-gitg commented on May 21, 2026

    @sasha-gitg
    Collaborator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

request clarification[Status] The maintainer need clarification or more information from the authorv2Affects only 2.0 versionweb[Component] This issue will be transferred to adk-web

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions