{"record":{"id":"620069d36817716d","repo":"BerriAI/litellm","slug":"invalid-authorization-header-format-expected-bea-620069","errorCode":null,"errorMessage":"Invalid authorization header format. Expected 'Bearer <token>'","messagePattern":"Invalid authorization header format\\. Expected 'Bearer <token>'","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"cookbook/mock_prompt_management_server/mock_prompt_management_server.py","lineNumber":181,"sourceCode":"\n\ndef verify_api_key(authorization: Optional[str] = Header(None)) -> bool:\n    \"\"\"\n    Verify the API key from the Authorization header.\n\n    Args:\n        authorization: Authorization header (Bearer token)\n\n    Returns:\n        True if valid, raises HTTPException if invalid\n    \"\"\"\n    if authorization is None:\n        # Allow requests without authentication for testing\n        return True\n\n    # Extract token from \"Bearer <token>\"\n    if not authorization.startswith(\"Bearer \"):\n        raise HTTPException(\n            status_code=status.HTTP_401_UNAUTHORIZED,\n            detail=\"Invalid authorization header format. Expected 'Bearer <token>'\",\n        )\n\n    token = authorization.replace(\"Bearer \", \"\").strip()\n\n    if token not in VALID_API_TOKENS:\n        raise HTTPException(\n            status_code=status.HTTP_401_UNAUTHORIZED,\n            detail=\"Invalid API key\",\n        )\n\n    return True\n\n\n@app.get(\"/beta/litellm_prompt_management\", response_model=PromptResponse)\nasync def get_prompt(\n    prompt_id: str = Query(..., description=\"The ID of the prompt to fetch\"),","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/cookbook/mock_prompt_management_server/mock_prompt_management_server.py#L163-L199","documentation":"The async-client type guard on the cancel path: with _is_async=True, cancel_fine_tuning_job requires an AsyncOpenAI or AsyncAzureOpenAI client. If a synchronous client was resolved or passed, awaiting the cancel call would fail at runtime, so this ValueError raises early with an explicit message. Purely a local client-type mismatch.","triggerScenarios":"Calling the async cancel path (await litellm.acancel_fine_tuning_job(...)) while passing a sync OpenAI() client, or letting the handler resolve a sync client for an async operation.","commonSituations":"Async orchestration daemons reusing a sync client singleton; refactoring sync job-management code to asyncio without updating client construction; mixing sync creation and async cancellation in the same module.","solutions":["Construct and pass AsyncOpenAI(api_key=...) for async cancellation.","Or omit the custom client and let litellm create the async client from the environment key.","Or keep cancellation synchronous with cancel_fine_tuning_job()."],"exampleFix":"# before\nawait litellm.acancel_fine_tuning_job(fine_tuning_job_id=\"ftjob-abc\", client=OpenAI())\n\n# after\nawait litellm.acancel_fine_tuning_job(fine_tuning_job_id=\"ftjob-abc\", client=AsyncOpenAI())","handlingStrategy":"type-guard","validationCode":"from openai import AsyncOpenAI\n\ndef assert_async_client_for_cancel(client: object) -> None:\n    assert isinstance(client, AsyncOpenAI), f\"expected AsyncOpenAI, got {type(client).__name__}\"","typeGuard":"from openai import AsyncOpenAI, AsyncAzureOpenAI\n\ndef is_usable_async_client(client: object) -> bool:\n    return isinstance(client, (AsyncOpenAI, AsyncAzureOpenAI))","tryCatchPattern":"try:\n    await litellm.acancel_fine_tuning_job(fine_tuning_job_id=jid, client=client)\nexcept ValueError as e:\n    if \"AsyncOpenAI\" in str(e):\n        from openai import AsyncOpenAI\n        await litellm.acancel_fine_tuning_job(fine_tuning_job_id=jid, client=AsyncOpenAI())\n    else:\n        raise","preventionTips":["Keep one client factory keyed by sync/async so cancellation daemons always get async clients.","Add isinstance asserts at wiring time to fail at startup, not at cancel time."],"tags":["openai","fine-tuning","async","type-mismatch","litellm"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}