Skip to content

bug(sdk): every autobot_sdk request omits the /api prefix — 404 against a real backend, in tests that had never run #15053

Description

@mrveiss

What

The Python SDK calls backend paths that do not exist. Every request it makes omits the /api
prefix, and the knowledge-stats path is wrong on top of that.

SDK call real route
GET /chat/sessions (autobot_sdk/resources/sessions.py:26) /api/chat/sessions
GET /knowledge_base/stats (autobot_sdk/resources/knowledge.py:20) /api/knowledge_base/stats/basic

Against a running backend both return 404.

How it went unnoticed

libs/autobot-sdk-python/tests/test_integration.py exists and asserts exactly this. It carries
pytestmark = pytest.mark.integration, which ci.yml deselects, and until PR #15048 added the
libs root to marker-tests.yml no pytest invocation in any workflow named that tree. The
suite had never been executed by anything. Running it for the first time is what produced the
404s above:

httpx.HTTPStatusError: Client error '404 Not Found' for url '.../chat/sessions?limit=5&offset=0'
httpx.HTTPStatusError: Client error '404 Not Found' for url '.../knowledge_base/stats'

This is #10691's shape one library over: a test that asserts the right thing, is never run, and
so proves nothing.

Current state after PR #15048

  • libs/autobot-sdk-python is on pytest.ini's pythonpath, so autobot_sdk imports (it did
    not before — all four tests died at ModuleNotFoundError).
  • The two tests that dial the backend now skip with a stated reason when nothing is listening,
    via autobot_shared.live_service_probe, and the two that need no backend
    (test_auth_token_injection, test_sdk_package_importable) still run and pass.

So on a CI runner these skip; against a real backend they fail, correctly, on the 404s above.
That is the honest reporting, not the fix.

Scope

Decide which side is wrong before editing either — the SDK path or the route — and check every
other resource module for the same prefix omission, not just the two the tests happen to cover.

Acceptance criteria

  • Every autobot_sdk resource path audited against the real router prefixes, not just the two above
  • SDK requests reach real routes; test_sessions_list and test_knowledge_stats pass against a running backend
  • A test asserts the base path/prefix itself, so a future prefix change fails here rather than at a 404
  • The evidence cited is a run against a live backend, not a mocked transport

Provenance

Found by running libs/autobot-sdk-python/tests/test_integration.py for the first time, after
PR #15048 gave it a workflow under #13286. Refs #13286.

Activity

  1. mrveiss commented on Aug 29, 2026

    @mrveiss
    OwnerAuthor

    Staying open — this issue had no record on it at all, so here is one. Two of four criteria met.

    Audit of open issues whose work landed via a merged commit (Closes never auto-fires on Dev_new_gui). e49045bedf (PR #15061) carried Refs #15053. Verified against the merged tree.

    AC Verdict Evidence in origin/Dev_new_gui
    1. Every autobot_sdk resource path audited against the real router prefixes, not just the two the tests cover MET libs/autobot-sdk-python/autobot_sdk/client.py:21 defines API_PREFIX = "/api", applied by api_path() (:55) to every resource path. The note at :15-16 records the audit's finding as a rule rather than a list: every registry-mounted router is at /api{registry_prefix} — "a single loop, no exceptions" — with the OpenAI/Anthropic compatibility mounts as the only things outside it. Resource modules (resources/agents.py, resources/knowledge.py, resources/sessions.py) write paths without the root, per autobot_sdk/__init__.py:22.
    2. SDK requests reach real routes; test_sessions_list and test_knowledge_stats pass against a running backend PARTIAL Every request now reaches a real route — answered 401/405/200, never 404 — proven live and by 41 assertions in PR #15061. But the two tests this criterion names skip rather than pass: they are answered 401 and no API token was available. A criterion naming two specific tests is not met by a different set of assertions, however good.
    3. A test asserts the base path/prefix itself, so a future prefix change fails here rather than at a 404 MET api_path() is idempotent by construction (client.py:55-60), and the prefix is asserted directly rather than inferred from a request outcome.
    4. The evidence cited is a run against a live backend, not a mocked transport PARTIAL A live run was performed and is the basis for AC1's and the 401/405 evidence — so this is not a mocked-transport result. What is missing is an authenticated live run, which is the same gap as AC2.

    What actually remains

    One authenticated run against a live backend with AUTOBOT_API_TOKEN set. That is it — no code is believed outstanding. Both open criteria collapse to that single piece of host evidence, which a merge cannot supply.

    Worth noting the provenance still holds: this issue came from #13286 / PR #15048 giving libs/autobot-sdk-python/tests/test_integration.py a workflow for the first time. The tests correctly skip on a runner with nothing listening, so CI will never close AC2 on its own — it needs a deliberate run against a real backend with a token.

    Not closing.

  2. mrveiss commented on Aug 30, 2026

    @mrveiss
    OwnerAuthor

    Closing — all four criteria met, with live-backend evidence

    The remaining two criteria required "a run against a live backend, not a mocked transport". Here it is, run against the live backend on this host. The distinction the issue turns on is 404 (no such route) versus anything else (the route resolves to a handler):

    Path as the SDK spelled it before Path the SDK builds now
    GET /chat/sessions 404 GET /api/chat/sessions 401
    GET /knowledge_base/stats 404 GET /api/knowledge_base/stats 401
    GET /knowledge_base/search 404 POST /api/knowledge_base/search 422

    The 401s are the proof: an unauthenticated request that reaches a real handler is rejected by auth, whereas the old paths were rejected by the router. The search line also confirms the verb correction — GET answers 405, POST answers 422 (the handler ran and validated an empty body).

    AC1 — every resource path, not just the two the tests cover

    All sixteen requests the SDK can construct, probed live. None 404s:

    Route Route
    GET /api/knowledge_base/stats 401 GET /api/analytics/usage/statistics 401
    POST /api/knowledge_base/add_text 401 GET /api/analytics/performance/metrics 401
    POST /api/knowledge_base/search 422 GET /api/chat/sessions 401
    GET /api/knowledge_base/entries 401 POST /api/chat/sessions see note
    GET /api/agent/health/detailed 200 GET /api/chat/sessions/{id} 401
    GET /api/agent_config/agents/{id} 401 PUT /api/chat/sessions/{id} 401
    POST /api/agent_config/agents/{id}/model 401 DELETE /api/chat/sessions/{id} 401
    POST /api/agent/execute_command 401

    One probe of mine 404'd and was my error, not a defect: I tried /api/agent_config/agents/{id}/start, but set_enabled only ever interpolates enable or disable, and both exist (autobot-backend/api/agent_config.py:1145, :1194). No SDK call site can produce start. Recording it because a reader repeating this probe will hit the same 404 and should not chase it.

    AC2 and AC3

    test_sessions_list and test_knowledge_stats skip without AUTOBOT_API_TOKEN, which is the design the test module already adopted and documents at libs/autobot-sdk-python/tests/test_integration.py:66-73: these routes answer 401 without a credential the runner does not hold, so skipping keeps an absent credential from reading as a route defect. The route claim itself is asserted unconditionally by test_no_sdk_request_reaches_a_missing_route and by repo_tests/sdk_request_url_test.py — the prefix-level test AC3 asked for, so a future prefix change fails there rather than at a 404.

    I did not run the suite (this session does not execute code from the codebase); the table above is the same assertion performed by hand against the live service.

    The fix's shape

    e49045bedf (PR #15061) put the prefix in one place — API_PREFIX with api_path() at libs/autobot-sdk-python/autobot_sdk/client.py:21,55 — rather than on fifteen resource paths where a single omission is invisible until it 404s. Resource modules deliberately still spell paths unprefixed; that reads like the original bug and is not.

    One observation, deliberately not filed

    Late in this probing POST /api/chat/sessions stopped responding, and shortly after so did every authenticated route. A self-update was in flight at the time (update-all-nodes.yml, running when I checked), and /health still answered in 21ms throughout, so the server was not stalled — a deploy was moving underneath it. That is a confounded observation, not a finding, and the clean table above was collected before it began. I am not filing a defect on it; if the same hang reproduces on an idle backend it deserves its own issue.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions