elastic / elasticsearch-net

This strongly-typed, client library enables working with Elasticsearch. It is the official client maintained and supported by Elastic.
https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/index.html
Apache License 2.0
15 stars 1.15k forks source link

Elastic.Transport.UnexpectedTransportException: Index name is null for the given type and no default index is set (BulkDeleteOperation) #7988

Open yansklyarenko opened 1 year ago

yansklyarenko commented 1 year ago

Elastic.Clients.Elasticsearch version: 8.11.0

Elasticsearch version: 8.2.2

.NET runtime version: net7.0

Operating system version: Windows 10

Description of the problem including expected versus actual behavior: Prerequisites: there's an index "my-test-index" containing a document with id equals "1".

Consider the following code:

var deleteOperation = new BulkDeleteOperation<IReadOnlyDictionary<string, object>>("1");
var deleteBulkRequest = new BulkRequest("my-test-index") { Operations = new BulkOperationsCollection { deleteOperation } };
var deleteResponse = await client.BulkAsync(deleteBulkRequest).ConfigureAwait(false);

The call to BulkAsync fails with the following exception:

# FailureReason: Unrecoverable/Unexpected BadRequest while attempting POST on https://localhost:9292/my-test-index/_bulk?pretty=true&error_trace=true
 - [1] BadRequest: Node: https://localhost:9292/ Exception: ArgumentException Took: 00:00:00.0059842
# Audit exception in step 1 BadRequest:
System.ArgumentException: Index name is null for the given type and no default index is set. Map an index name using ConnectionSettings.DefaultMappingFor<TDocument>() or set a default index using ConnectionSettings.DefaultIndex().
   at Elastic.Clients.Elasticsearch.IndexNameResolver.ValidateIndexName(String indexName) in /_/src/Elastic.Clients.Elasticsearch/Core/Infer/IndexName/IndexNameResolver.cs:line 49
   at Elastic.Clients.Elasticsearch.IndexNameResolver.Resolve(Type type) in /_/src/Elastic.Clients.Elasticsearch/Core/Infer/IndexName/IndexNameResolver.cs:line 39
   at Elastic.Clients.Elasticsearch.IndexNameResolver.Resolve(IndexName i) in /_/src/Elastic.Clients.Elasticsearch/Core/Infer/IndexName/IndexNameResolver.cs:line 24
   at Elastic.Clients.Elasticsearch.IndexNameConverter.Write(Utf8JsonWriter writer, IndexName value, JsonSerializerOptions options) in /_/src/Elastic.Clients.Elasticsearch/Core/Infer/IndexName/IndexNameConverter.cs:line 50
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteUsingSerializer[TValue](Utf8JsonWriter writer, TValue& value, JsonTypeInfo jsonTypeInfo)
   at System.Text.Json.JsonSerializer.Serialize[TValue](Utf8JsonWriter writer, TValue value, JsonSerializerOptions options)
   at Elastic.Clients.Elasticsearch.Core.Bulk.BulkDeleteOperation.SerializeInternal(IElasticsearchClientSettings settings, Utf8JsonWriter writer) in /_/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperation.cs:line 47
   at Elastic.Clients.Elasticsearch.Core.Bulk.BulkDeleteOperation.SerializeAsync(Stream stream, IElasticsearchClientSettings settings) in /_/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperation.cs:line 32
   at Elastic.Clients.Elasticsearch.Core.Bulk.BulkDeleteOperation.SerializeAsync(Stream stream, IElasticsearchClientSettings settings) in /_/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperation.cs:line 33
   at Elastic.Clients.Elasticsearch.BulkRequest.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting) in /_/src/Elastic.Clients.Elasticsearch/Api/BulkRequest.cs:line 66
   at Elastic.Transport.PostData.SerializableData`1.WriteAsync(Stream writableStream, ITransportConfiguration settings, CancellationToken cancellationToken)
   at Elastic.Transport.HttpTransportClient.SetContentAsync(HttpRequestMessage message, RequestData requestData, CancellationToken cancellationToken)
   at Elastic.Transport.HttpTransportClient.RequestCoreAsync[TResponse](Boolean isAsync, RequestData requestData, CancellationToken cancellationToken)
   at Elastic.Transport.DefaultRequestPipeline`1.CallProductEndpointCoreAsync[TResponse](Boolean isAsync, RequestData requestData, CancellationToken cancellationToken)
   at Elastic.Transport.DefaultHttpTransport`1.RequestCoreAsync[TResponse](Boolean isAsync, HttpMethod method, String path, PostData data, RequestParameters requestParameters, OpenTelemetryData openTelemetryData, CancellationToken cancellationToken)

As soon as the code is changed the following way (the index name IS NOT set for BulkRequest, but instead IS set for each BulkDeleteOperation):

var deleteOperation = new BulkDeleteOperation<IReadOnlyDictionary<string, object>>("1") { Index = "my-test-index" };
var deleteBulkRequest = new BulkRequest() { Operations = new BulkOperationsCollection { deleteOperation } };
var deleteResponse = await client.BulkAsync(deleteBulkRequest).ConfigureAwait(false);

It starts working just fine. So, the workaround is to mandatory specify the index for each bulk delete operation. This is not reproducible for bulk index operation, but IS reproducible if the bulk request contains AT LEAST ONE bulk delete operation. Specifying the index name on both levels doesn't help either.

Notes: I should say that the suggestion in the error message about using default index name in the settings is not relevant - in my app each BulkRequest might target a different index.

bonny-bonev commented 11 months ago

I saw this bug and I believe the same issue is the reason for the bug that I logged recently: https://github.com/elastic/elasticsearch-net/issues/8001 Thank you very much for the provided workaround!

anghelnicolae commented 8 months ago

Bug still present in v8.12 of the client.

tigranzalian-pt commented 3 months ago

Are there any fixes coming soon?