BerriAI/litellm · error · HTTPException

Prompt '{prompt_id}' not found. Available prompts: {list(PRO

Error message

Prompt '{prompt_id}' not found. Available prompts: {list(PROMPTS_DB.keys())}

What it means

The async-client type guard on the list path: when _is_async=True, list_fine_tuning_jobs requires the resolved client to be AsyncOpenAI or AsyncAzureOpenAI. Passing a synchronous OpenAI client (or resolving one) triggers this ValueError before the awaited list call, preventing a runtime 'object is not awaitable' failure. Local type mismatch only.

Source

Thrown at cookbook/mock_prompt_management_server/mock_prompt_management_server.py:239

    Raises:
        HTTPException: 401 if authentication fails, 404 if prompt not found
    """
    # Verify authentication
    verify_api_key(authorization)

    # Log the request parameters (useful for debugging)
    print(f"Fetching prompt: {prompt_id}")
    if project_name:
        print(f"  Project: {project_name}")
    if slug:
        print(f"  Slug: {slug}")
    if version:
        print(f"  Version: {version}")

    # Check if prompt exists
    if prompt_id not in PROMPTS_DB:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Prompt '{prompt_id}' not found. Available prompts: {list(PROMPTS_DB.keys())}",
        )

    # Get the prompt from the database
    prompt_data = PROMPTS_DB[prompt_id]

    # Optional: Apply filtering based on project_name, slug, or version
    # In a real implementation, you might use these to filter prompts by access control
    # or to fetch specific versions from your database

    return PromptResponse(**prompt_data)


@app.get("/health")
async def health_check():
    """Health check endpoint"""
    return {

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Pass AsyncOpenAI(...) instead of OpenAI(...) for async listing.
  2. Or remove the custom client and rely on OPENAI_API_KEY so litellm builds the async client.
  3. Or keep the sync list_fine_tuning_jobs() call.

Example fix

# before
jobs = await litellm.alist_fine_tuning_jobs(limit=20, client=OpenAI())

# after
jobs = await litellm.alist_fine_tuning_jobs(limit=20, client=AsyncOpenAI())
Defensive patterns

Strategy: type-guard

Validate before calling

from openai import AsyncOpenAI

def is_async_list_client(client: object) -> bool:
    return isinstance(client, AsyncOpenAI)

Type guard

from openai import AsyncOpenAI, AsyncAzureOpenAI

def is_usable_async_client(client: object) -> bool:
    return isinstance(client, (AsyncOpenAI, AsyncAzureOpenAI))

Try / catch

try:
    jobs = await litellm.alist_fine_tuning_jobs(limit=20, client=client)
except ValueError as e:
    if "AsyncOpenAI" in str(e):
        from openai import AsyncOpenAI
        jobs = await litellm.alist_fine_tuning_jobs(limit=20, client=AsyncOpenAI())
    else:
        raise

Prevention

When it happens

Trigger: Calling await litellm.alist_fine_tuning_jobs(...) (or the async branch) with client=OpenAI(...), or in a context where a sync client is resolved for the async path.

Common situations: Async dashboards reusing sync client singletons; upgrading sync polling loops to asyncio without changing client instantiation; generic client factory helpers that always return sync clients.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/75c8025d40fab81f. Report an issue: GitHub.