Skip to content

Two source docblocks still say /ai/* 404s "AI service is not configured" — the dispatcher has answered 501 since the shared capabilityUnavailable exit landed #16211

Description

@os-litant

Found while working #16142: the card's replacement text needed the real behaviour of /api/v1/ai/** when no AI service is mounted, and the two docblocks a reader would reach for disagree with the code. Recorded only — not claimed, no assignee. Out of scope for #16142, which is a README-only content fix.

What the code does

packages/runtime/src/domains/ai.ts, the unserveable-slot branch:

if (!isServiceServeable(aiService)) {
    if (denyAnonymous) return anonymousRefusal();
    if (method === 'GET' && subPath === '/ai/agents') {
        return { handled: true, response: deps.success({ agents: [] }) };
    }
    // 501, not 404: `/ai/*` IS mounted, so the request reached a handler
    // with nothing behind it — see ./unavailable.ts.
    return capabilityUnavailable(deps, 'ai');
}

and packages/runtime/src/domains/unavailable.ts returns deps.error(serviceUnavailableMessage(slot), 501), with a docblock that draws the 404-vs-501 distinction deliberately ("The route is not there" = 404, handled by the host router; "The route is there; the implementation is not" = 501).

So: every /ai/* route answers 501 with the same remedy sentence discovery reports under services.ai, except GET /ai/agents, which answers 200 with an empty list.

What two docblocks say

Both still describe the pre-capabilityUnavailable behaviour:

  • packages/client/src/index.ts:5129-5133 — "This repo's dispatcher only proxies /api/v1/ai/** to whatever buildAIRoutes() mounted, and 404s AI service is not configured when the service is absent (the open-source default)".
  • packages/runtime/src/route-ledger.ts:401 — "the dispatcher only proxies (or 404s "AI service is not configured")".

packages/spec/src/api/protocol.zod.ts:2736 carries the same sentence in a comment. The docs site is already correct: content/docs/api/client-sdk.mdx says "the route is mounted but unimplemented, so it answers 501 and discovery reports the slot unavailable with the same sentence".

Two further details the stale text loses: the message is no longer a local string at all (it comes from serviceUnavailableMessage, so the 501 body and the discovery entry cannot drift), and the GET /ai/agents empty-list courtesy is not mentioned anywhere in the client docblock, which is the one an SDK reader actually opens.

Why it matters

packages/client/src/index.ts is a published package's source, and its ai docblock is the SDK's own account of what a caller sees without the Cloud/EE service. A caller who codes if (res.status === 404) off that docblock does not handle the answer they will actually get — and 404-vs-501 is exactly the distinction unavailable.ts exists to make: 404 now means the path does not exist, which for /ai/* is false.

Executable criterion

grep -rn '404s' packages/client/src/index.ts packages/runtime/src/route-ledger.ts returns the two claims above; the branch they describe returns capabilityUnavailable(deps, 'ai') → 501. After the fix both read 501, and the GET /ai/agents exception is stated in the client docblock.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions