Skip to content

[PredictionServiceClient] Bug in embedContent and EmbedContentRequest: Invalid model/endpoint mappings causing INVALID_ARGUMENT or undefined method errors #9276

Description

@Jony-Shark

When attempting to use PredictionServiceClient::embedContent() with the newer EmbedContentRequest class, the underlying gRPC bindings fail to resolve the model or endpoint correctly. This makes it impossible to use the native text-embedding endpoints via the official PHP SDK.

Steps to reproduce:
If we try to construct the request by setting the model using setModel():

use Google\Cloud\AIPlatform\V1\Client\PredictionServiceClient;
use Google\Cloud\AIPlatform\V1\EmbedContentRequest;
use Google\Cloud\AIPlatform\V1\Content;
use Google\Cloud\AIPlatform\V1\Part;
 
$client = new PredictionServiceClient([
    'apiEndpoint' => 'us-central1-aiplatform.googleapis.com',
    'credentials' => '/path/to/credentials.json'
]);
 
$content = (new Content())->setParts([(new Part())->setText('Hello world')]);
 
$req = new EmbedContentRequest();
$req->setModel('projects/MY_PROJECT/locations/us-central1/publishers/google/models/text-embedding-004');
$req->setContent($content);
 
$res = $client->embedContent($req);

Actual Result: An ApiException is thrown from the backend:

{
    "message": "Invalid value (oneof), oneof field '_model' is already set. Cannot set 'model'",
    "code": 3,
    "status": "INVALID_ARGUMENT",
    "details": [ ... ]
}

If we try to supply an endpoint via the $optionalArgs to bypass the model binding:

$res = $client->embedContent($req, [
    'endpoint' => 'projects/MY_PROJECT/locations/us-central1/publishers/google/models/text-embedding-004'
]);

Actual Result:

Google\ApiCore\ValidationException: Could not map bindings for google.cloud.aiplatform.v1.PredictionService/EmbedContent to any Uri template.

If we attempt to use setEndpoint() on the request object itself (which is available on PredictRequest but seems to be missing here):

$req->setEndpoint('projects/MY_PROJECT/locations/us-central1/publishers/google/models/text-embedding-004');

Actual Result:

Fatal error: Call to undefined method Google\Cloud\AIPlatform\V1\EmbedContentRequest::setEndpoint()

Expected Result:
The EmbedContentRequest should properly bind the model parameter to the gRPC URI template (e.g. /v1/{model=projects//locations//publishers//models/}:embedContent) without throwing a protobuf oneof conflict (_model vs model), and should successfully return the EmbedContentResponse.

Workaround (for others facing this issue):

Currently, the only way to get embeddings via PHP is to bypass EmbedContentRequest and use the older PredictRequest with raw Protobuf Structs:

$instanceValue = new \Google\Protobuf\Value();
$struct = new \Google\Protobuf\Struct();
$struct->setFields(['content' => (new \Google\Protobuf\Value())->setStringValue('Hello World')]);
$instanceValue->setStructValue($struct);
 
$request = (new PredictRequest())
    ->setEndpoint('projects/MY_PROJECT/locations/us-central1/publishers/google/models/text-embedding-004')
    ->setInstances([$instanceValue]);
 
$response = $client->predict($request);

Environment details:
OS: Linux
PHP version: 8.0+
Package name and version: google/cloud-ai-platform (Tested on versions ^1.13.0 up to 1.60.1)

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