Skip to content

Conversation

@infjdeepak
Copy link

What:

  • Bug Fix
  • New Feature

Description:

OpenAI sometimes returns error payloads with Content-Type: text/plain.
The current ErrorResponseHandler ignores these responses, preventing
exceptions from being parsed correctly.

This patch updates the Content-Type check to allow both JSON and text/plain
content types, enabling consistent error handling.

The fix is backward compatible and does not change behavior for valid JSON
responses.

For example, calling embeddings()->create() with an invalid request results in the following runtime error instead of a clean ErrorException:

$client = OpenAI::client($yourApiKey);

$response = $client->embeddings()->create([
    'model' => 'text-embedding-3-small',
    'input' => 'The food was delicious and the waiter...',
]);

Produces:

PHP Warning:  Undefined array key "data" in vendor/openai-php/client/src/Responses/Embeddings/CreateResponse.php on line 47
PHP Fatal error:  Uncaught TypeError: array_map(): Argument #2 ($array) must be of type array, null given
    in vendor/openai-php/client/src/Responses/Embeddings/CreateResponse.php:45

Related:

N/A

@infjdeepak infjdeepak force-pushed the fix/plain-text-error-handling branch from d964f42 to 4d1746d Compare December 11, 2025 07:05
@iBotPeaches
Copy link
Collaborator

Thanks!!

I really thought I squashed this for good with: #643

Do you have a sample payload of the plain text one? Trying to see if it's an error or the payload wrongly typed. Additionally what the http status code is.

We would want to add a test for what you saw as methods are handled differently based on type of return (json, mixed, etc)

@idsdeepak
Copy link

Here’s a plain text response I received:
Status Code: 401
Content-Type: text/plain
Response Body:
Incorrect API key provided: sk-invalid-key. You can find your API key at https://platform.openai.com/account/api-keys.

* Host api.openai.com:443 was resolved.
* IPv6: (none)
* IPv4: 162.159.140.245, 172.66.0.243
*   Trying 162.159.140.245:443...
* Connected to api.openai.com (162.159.140.245) port 443
* ALPN: curl offers http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519 / id-ecPublicKey
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: CN=api.openai.com
*  start date: Nov 14 00:26:50 2025 GMT
*  expire date: Feb 12 01:26:48 2026 GMT
*  subjectAltName: host "api.openai.com" matched cert's "api.openai.com"
*  issuer: C=US; O=Google Trust Services; CN=WE1
*  SSL certificate verify ok.
*   Certificate level 0: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA256
*   Certificate level 1: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA384
*   Certificate level 2: Public key type EC/secp384r1 (384/192 Bits/secBits), signed using ecdsa-with-SHA384
* using HTTP/1.x
> POST /v1/embeddings HTTP/1.1
Host: api.openai.com
User-Agent: GuzzleHttp/7
Authorization: Bearer sk-invalid-key
Content-Type: application/json
Content-Length: 85

* old SSL session ID is stale, removing
< HTTP/1.1 401 Unauthorized
< Date: Thu, 11 Dec 2025 10:38:16 GMT
< Content-Type: text/plain
< Content-Length: 260
< Connection: keep-alive
< x-openai-ide-error-code: invalid_api_key
< x-openai-authorization-error: 401
< x-error-json: ewogICJlcnJvciI6IHsKICAgICJtZXNzYWdlIjogIkluY29ycmVjdCBBUEkga2V5IHByb3ZpZGVkOiBzay1pbnZhbCoqLWtleS4gWW91IGNhbiBmaW5kIHlvdXIgQVBJIGtleSBhdCBodHRwczovL3BsYXRmb3JtLm9wZW5haS5jb20vYWNjb3VudC9hcGkta2V5cy4iLAogICAgInR5cGUiOiAiaW52YWxpZF9yZXF1ZXN0X2Vycm9yIiwKICAgICJjb2RlIjogImludmFsaWRfYXBpX2tleSIsCiAgICAicGFyYW0iOiBudWxsCiAgfSwKICAic3RhdHVzIjogNDAxCn0=
< x-request-id: req_7395a80aa5f242fb9c37413bff232dc8
< x-datadog-trace-id: 17930003501829985854
< x-datadog-parent-id: 9435506756333248072
< x-datadog-sampling-priority: 0
< x-openai-internal-caller: unknown_through_ide
< x-envoy-upstream-service-time: 13
< x-openai-proxy-wasm: v0.1
< cf-cache-status: DYNAMIC
< Set-Cookie: __cf_bm=D17mff4GC0psLB03NqziY9O_p.cqQdFUWj3LLY3v9YY-1765449496-1.0.1.1-MQXflU39EvijLirKNa062tAfb0mso6Pyx2._Q1HTUDL7ytpJDQp2SbHa36ymzUd94xwwEHheF68sAYDI80LBMtAcGCtVcOE0gyQVHjAryaw; path=/; expires=Thu, 11-Dec-25 11:08:16 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
< Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
< X-Content-Type-Options: nosniff
< Set-Cookie: _cfuvid=6pf9oThr3mq.JuIsZfqJvAggmDQmmBTu7ww3KXEZCfQ-1765449496677-0.0.1.1-604800000; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
< Server: cloudflare
< CF-RAY: 9ac459f8793f91b5-DEL
< alt-svc: h3=":443"; ma=86400
< 
* Connection #0 to host api.openai.com left intact

Caught Exception: Incorrect API key provided: sk-inval**-key. You can find your API key at https://platform.openai.com/account/api-keys.

Payload:

$client = OpenAI::client($yourApiKey);

try {
    $response = $client->embeddings()->create([
        'model' => 'text-embedding-3-small',
        'input' => 'The food was delicious and the waiter...',
    ]);

} catch (\Exception $e) {
    echo "test error" . $e->getMessage();
}

@iBotPeaches
Copy link
Collaborator

Interesting. Let me mess with this is a bit. I wonder if we accept application/json will the message become json instead of plain text.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants