Profiles·Public

@elastic/elasticsearch

semver>=7.0.0 <10.0.0postconditions32functions22last verified2026-06-23coverage score100%

Postconditions: what we check

  • search · api-error
    error
    WhenAny network or HTTP failure: connection refused, timeout, 4xx or 5xx response (including 400 bad request, 401 unauthorized, 403 forbidden, 404 index not found, 429 too many requests, 5xx server error)
    ThrowsResponseError (4xx/5xx HTTP response, contains meta.statusCode and meta.body), ConnectionError (TCP failure, TLS error), TimeoutError (requestTimeout exceeded), or NoLivingConnectionsError (all pool nodes unreachable)
    Required handlingCaller MUST wrap in try-catch. Elasticsearch network and server errors will propagate and crash the caller if uncaught. Minimum handling: try { const result = await client.search({ index: 'my-index', query: { ... } }); } catch (err) { if (err instanceof errors.ResponseError) { // HTTP error — check err.meta.statusCode } else if (err instanceof errors.ConnectionError) { // Network failure } } Import error types: import { errors } from '@elastic/elasticsearch'
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • index · api-error
    error
    WhenAny network or HTTP failure: connection refused, timeout, 4xx or 5xx response (including 409 version conflict, 429 too many requests, 5xx server error)
    ThrowsResponseError (4xx/5xx HTTP response), ConnectionError (network failure), TimeoutError (requestTimeout exceeded), or NoLivingConnectionsError
    Required handlingCaller MUST wrap in try-catch. Write operations that silently fail will cause data loss. Version conflicts (409) and capacity errors (429) require explicit handling for correct behavior.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • get · api-error
    error
    WhenDocument not found (404), connection failure, timeout, or other HTTP error
    ThrowsResponseError with meta.statusCode=404 when document not found; ResponseError for other HTTP errors; ConnectionError or TimeoutError for network failures
    Required handlingCaller MUST wrap in try-catch. A missing document throws instead of returning null — callers that skip try-catch will crash when any document is absent. Handle 404 explicitly: try { const doc = await client.get({ index: 'my-index', id: '123' }); } catch (err) { if (err instanceof errors.ResponseError && err.meta.statusCode === 404) { // Document not found — handle gracefully } else { throw err; } }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • delete · api-error
    error
    WhenDocument not found (404), connection failure, timeout, or HTTP error
    ThrowsResponseError (including 404 when document is absent), ConnectionError, TimeoutError, or NoLivingConnectionsError
    Required handlingCaller MUST wrap in try-catch. Deleting a non-existent document throws ResponseError (404) — this must be handled or idempotent delete will crash.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • update · api-error
    error
    WhenDocument not found (404), version conflict (409), connection failure, timeout, or other HTTP error
    ThrowsResponseError (404 if document absent, 409 on version conflict, 5xx on server error), ConnectionError, TimeoutError, or NoLivingConnectionsError
    Required handlingCaller MUST wrap in try-catch. Version conflicts (409) are common under concurrent write load and require application-level retry or conflict resolution.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • bulk · api-error
    error
    WhenConnection failure, timeout, or HTTP-level failure (the entire request fails)
    ThrowsConnectionError, TimeoutError, ResponseError (on HTTP 4xx/5xx for the bulk request itself, not individual item failures), or NoLivingConnectionsError
    Required handlingCaller MUST wrap in try-catch for connection/HTTP-level failures, AND check response.errors after a successful Promise resolution for per-item failures. Full handling: try { const response = await client.bulk({ operations: [...] }); if (response.errors) { for (const item of response.items) { const op = item.index || item.create || item.update || item.delete; if (op?.error) console.error('Item failed:', op.error); } } } catch (err) { // Connection/HTTP failure for the bulk request }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][3][2]
  • count · api-error
    error
    WhenConnection failure, timeout, 4xx or 5xx HTTP response
    ThrowsResponseError (4xx/5xx HTTP response), ConnectionError (network failure), TimeoutError (requestTimeout exceeded), or NoLivingConnectionsError
    Required handlingCaller MUST wrap in try-catch. Count queries against non-existent indices will throw ResponseError (404). Network failures will propagate uncaught.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • scroll · api-error
    error
    WhenScroll context expired (404), connection failure, timeout, or HTTP error
    ThrowsResponseError (including 404 when scroll context expires), ConnectionError, TimeoutError, or NoLivingConnectionsError
    Required handlingCaller MUST wrap in try-catch. Scroll contexts expire after the configured TTL — callers that loop without try-catch will crash when the scroll expires.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][2]
  • mget · mget-found-not-checked
    warning
    Whenmget() resolves successfully even when requested documents do not exist. Each doc in response.docs[] has a found: boolean field — callers that omit this check will silently treat missing documents as present.
    Required handlingCaller MUST handle this condition appropriately.
    costmediumin prodsilent failureusers seelost datavisibilitysilent
    Sources[4][2]
  • mget · mget-api-error
    error
    WhenConnection failure, auth error, or HTTP-level failure (not per-doc 404). The Promise only rejects when the entire request fails, not when individual documents are missing.
    Required handlingCaller MUST wrap in try-catch. HTTP-level failures reject the entire Promise with ConnectionError, TimeoutError, or ResponseError.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4][2]
  • create · create-api-error
    error
    WhenDocument with same ID already exists (409), or connection failure, auth error, or HTTP-level failure (400, 401, 403, 5xx).
    Required handlingCaller MUST wrap in try-catch. The 409 conflict is the distinctive error: try { await client.create({ index: 'my-index', id: docId, document: doc }); } catch (err) { if (err instanceof errors.ResponseError && err.meta.statusCode === 409) { // Document already exists — decide whether to update or skip } else { throw err; } }
    costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[5][2]
  • deleteByQuery · deletebyquery-failures-not-checked
    error
    WhendeleteByQuery() resolves successfully even when some documents fail to delete. The response.failures[] array contains per-document deletion errors. Callers that omit this check have silent partial deletes — some targeted documents remain while others are deleted.
    Required handlingAfter await, always check response.failures: const response = await client.deleteByQuery({ index: 'my-index', query: { ... } }); if (response.failures && response.failures.length > 0) { // Some documents were not deleted for (const failure of response.failures) { console.error('Delete failed for shard:', failure.shard, failure.reason); } }
    costhighin prodsilent failureusers seelost datavisibilitysilent
    Sources[6][2]
  • deleteByQuery · deletebyquery-api-error
    error
    WhenConnection failure, auth error (401/403), or HTTP-level failure. Version conflicts abort the operation by default (conflicts: 'abort') — callers on high-concurrency indices may see 409-based aborts.
    Required handlingCaller MUST wrap in try-catch. Network errors and auth failures reject the Promise and must be caught to prevent uncaught exception crashes.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[6][2]
  • updateByQuery · updatebyquery-failures-not-checked
    error
    WhenupdateByQuery() resolves successfully even when some documents fail to update. The response.failures[] array contains per-document update errors. Callers that omit this check leave the index in a partially updated, inconsistent state.
    Required handlingAfter await, always check response.failures: const response = await client.updateByQuery({ index: 'my-index', script: { source: 'ctx._source.status = "archived"' }, query: { ... } }); if (response.failures && response.failures.length > 0) { // Some documents were not updated — handle inconsistency }
    costhighin prodsilent failureusers seelost datavisibilitysilent
    Sources[7][2]
  • updateByQuery · updatebyquery-api-error
    error
    WhenConnection failure, auth error (401/403), or HTTP-level failure. Version conflicts abort the operation by default — callers on high-concurrency indices may see 409-based aborts leaving partial updates in place.
    Required handlingCaller MUST wrap in try-catch. Network errors and auth failures reject the Promise and must be caught to prevent uncaught exception crashes.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[7][2]
  • helpers.bulk · helpers-bulk-ondrop-not-provided
    error
    Whenhelpers.bulk() calls the onDrop callback (not throw) for documents that exceed maxRetries or fail permanently. If no onDrop is provided, it defaults to noop — dropped documents are silently discarded. The Promise resolves with BulkStats.failed > 0 but callers have no way to identify which documents were lost.
    Required handlingAlways provide an onDrop handler and check BulkStats.failed: const stats = await client.helpers.bulk({ datasource: docs, onDocument: (doc) => ({ index: { _index: 'my-index' } }), onDrop: (dropped) => { console.error('Document dropped:', dropped.document, dropped.error); // Re-queue or alert on permanent failures } }); if (stats.failed > 0) { console.error(`${stats.failed} documents were not indexed`); }
    costhighin prodsilent failureusers seelost datavisibilitysilent
    Sources[3][2]
  • helpers.bulk · helpers-bulk-api-error
    error
    WhenHTTP-level failure (the entire request fails). Per-document failures are routed to onDrop, not thrown. The distinction is critical for correct handling.
    Required handlingCaller MUST wrap in try-catch for connection/HTTP-level failures. Per-document failures require a separate onDrop callback — both patterns are needed for complete error handling.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][2]
  • exists · exists-api-error
    error
    WhenConnection failure, auth errors (401/403), or malformed index names (400). Unlike get(), exists() does NOT throw ResponseError(404) for missing documents — it returns false. But network and auth errors still throw.
    Required handlingWrap in try-catch for network/auth errors: try { const docExists = await client.exists({ index: 'my-index', id: docId }); if (!docExists) { // Document does not exist — handle gracefully } } catch (err) { // Connection failure or auth error — not a missing document throw err; }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[8][2]
  • openPointInTime · openpit-api-error
    error
    WhenResponseError (403 if missing 'read' index privilege, 404 if index does not exist), ConnectionError, or TimeoutError. An uncaught error leaves the caller without a valid pit_id, causing subsequent search calls to fail with a malformed request.
    Required handlingCaller MUST wrap in try-catch. A failed openPointInTime() must abort the search workflow gracefully — without a valid pit_id, subsequent search calls will fail.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[9][2]
  • openPointInTime · openpit-not-closed
    warning
    WhenPIT IDs that are never closed with closePointInTime() accumulate on the Elasticsearch cluster. Each openPointInTime() call creates a server-side resource that prevents garbage collection of index segments and consumes file handles.
    Required handlingAlways close the PIT in a finally block: const { id: pitId } = await client.openPointInTime({ index: 'my-index', keep_alive: '1m' }); try { // paginated searches using pit_id: pitId } finally { await client.closePointInTime({ id: pitId }); }
    costmediumin proddegraded serviceusers seedegraded performancevisibilitysilent
    Sources[9][2]
  • close · close-api-error
    warning
    Whenclose() can throw ConnectionError or transport-level errors if connections fail to close cleanly. In long-running processes that create many Client instances (e.g., per-request clients), unclosed clients cause connection pool leaks.
    Required handlingAlways await close() and handle errors: try { await client.close(); } catch (err) { console.error('Client close failed:', err); }
    costlowin proddegraded serviceusers seedegraded performancevisibilitysilent
    Sources[2]
  • msearch · msearch-per-search-error-not-checked
    error
    Whenmsearch() resolves HTTP 200 even when individual searches fail. Each element in response.responses[] is either a successful result or an ErrorResponseBase object containing error.type and status. Callers that omit a per-response error check silently treat failed searches as empty results.
    Required handlingAfter await, check each response item for an error field: const response = await client.msearch({ searches: [ { index: 'products' }, { query: { match: { name: 'shoe' } } }, { index: 'orders' }, { query: { match: { status: 'pending' } } }, ] }); for (const result of response.responses) { if ('error' in result) { // Individual search failed — result.error.type and result.status console.error('Search failed:', result.status, result.error.type); } else { // Success — result.hits.hits contains documents } }
    costmediumin prodsilent failureusers seelost datavisibilitysilent
    Sources[10][11]
  • msearch · msearch-api-error
    error
    WhenConnection failure, auth error (401/403), or HTTP-level failure causes the entire msearch Promise to reject. This is distinct from per-search failures which return HTTP 200 with error objects in responses[].
    Required handlingCaller MUST wrap in try-catch for connection/HTTP-level failures AND check each responses[] item for per-search errors: try { const response = await client.msearch({ searches: [...] }); // Check individual results for per-search failures } catch (err) { if (err instanceof errors.ResponseError) { // HTTP-level error — the entire msearch request failed } else if (err instanceof errors.ConnectionError) { // Network failure } }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[10][1]
  • closePointInTime · closepit-not-called
    error
    WhenCallers that open a PIT with openPointInTime() but do not call closePointInTime() in a finally block will leak PIT resources on the Elasticsearch cluster whenever an exception occurs during the search workflow. Each leaked PIT holds segment locks and file handles until the keep_alive TTL expires.
    Required handlingAlways call closePointInTime() in a finally block: const { id: pitId } = await client.openPointInTime({ index: 'my-index', keep_alive: '1m' }); try { // paginated searches using pit_id: pitId let searchAfter; while (true) { const result = await client.search({ pit: { id: pitId, keep_alive: '1m' }, search_after: searchAfter, sort: [{ _shard_doc: 'asc' }] }); if (!result.hits.hits.length) break; searchAfter = result.hits.hits.at(-1)?.sort; } } finally { await client.closePointInTime({ id: pitId }); }
    costmediumin proddegraded serviceusers seedegraded performancevisibilitysilent
    Sources[12][9]
  • closePointInTime · closepit-api-error
    warning
    WhenclosePointInTime() throws on connection failure or auth error. If called with an invalid or already-expired PIT ID, the server resolves HTTP 200 with succeeded: false rather than throwing.
    Required handlingWrap in try-catch when called in finally blocks — a failed close must not suppress the original exception from the search workflow: } finally { try { await client.closePointInTime({ id: pitId }); } catch (closeErr) { console.error('Failed to close PIT:', closeErr); // Do not rethrow — preserve the original search exception } }
    costlowin proddegraded serviceusers seedegraded performancevisibilitysilent
    Sources[12]
  • clearScroll · clearscroll-not-called
    warning
    WhenCallers that use scroll() for pagination without calling clearScroll() when done (or when aborting early) leak scroll contexts on the Elasticsearch cluster. Scroll contexts are automatically freed after the TTL expires, but accumulating open scroll contexts (especially in high-throughput loops) consumes memory and open connections on the ES cluster.
    Required handlingAlways clear the scroll in a finally block: let scrollId; try { const initialResponse = await client.search({ index: 'my-index', scroll: '1m', size: 100 }); scrollId = initialResponse._scroll_id; let hits = initialResponse.hits.hits; while (hits.length > 0) { const response = await client.scroll({ scroll_id: scrollId, scroll: '1m' }); scrollId = response._scroll_id; hits = response.hits.hits; } } finally { if (scrollId) { await client.clearScroll({ scroll_id: scrollId }); } }
    costlowin proddegraded serviceusers seedegraded performancevisibilitysilent
    Sources[13]
  • clearScroll · clearscroll-api-error
    warning
    WhenclearScroll() throws on connection failure or auth error. If called with an invalid or already-expired scroll_id, it returns HTTP 200 with succeeded: false rather than throwing — callers need not special-case expired IDs.
    Required handlingWrap in try-catch when called in finally blocks — a failed clearScroll must not suppress the original exception from the scroll loop: } finally { if (scrollId) { try { await client.clearScroll({ scroll_id: scrollId }); } catch (err) { console.error('Failed to clear scroll:', err); } } }
    costlowin proddegraded serviceusers seedegraded performancevisibilitysilent
    Sources[13]
  • reindex · reindex-failures-not-checked
    error
    Whenreindex() resolves successfully even when individual document copies fail. The response.failures[] array contains per-document errors. When conflicts occur and conflicts: 'proceed' is set, the operation continues and errors accumulate in failures[]. Callers that omit this check leave the destination index in a partially populated state without detecting it.
    Required handlingAfter await, always check response.failures: const response = await client.reindex({ source: { index: 'source-index' }, dest: { index: 'dest-index' }, conflicts: 'proceed', // do not abort on version conflicts }); if (response.failures && response.failures.length > 0) { console.error(`Reindex completed with ${response.failures.length} failures`); for (const failure of response.failures) { console.error('Failed doc:', failure.id, failure.cause?.reason); } } console.log(`Reindexed: ${response.created} created, ${response.updated} updated`);
    costhighin prodsilent failureusers seelost datavisibilitysilent
    Sources[14][11]
  • reindex · reindex-api-error
    error
    WhenConnection failure, auth error (401/403), or HTTP-level failure rejects the Promise. Version conflicts abort the operation by default (conflicts: 'abort') and the response contains the failure count. If wait_for_completion: false, a task ID is returned and the task may fail independently.
    Required handlingCaller MUST wrap in try-catch. Reindex runs synchronously by default and can take minutes for large indices — connection failures mid-operation leave a partially indexed destination: try { const response = await client.reindex({ source: { index: 'old-index' }, dest: { index: 'new-index' }, }); if (response.failures?.length) { // Handle partial failures } } catch (err) { if (err instanceof errors.ResponseError) { // HTTP error — check err.meta.statusCode and err.meta.body.error.type } else if (err instanceof errors.TimeoutError) { // Request timed out — check if reindex task completed via tasks API } }
    costhighin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[14][1]
  • esql.query · esql-query-syntax-error
    error
    Whenesql.query() throws ResponseError with HTTP 400 when the ES|QL query has a syntax error, references an unknown column, or uses an unsupported function. Syntax errors in ES|QL are not detected at build time — they manifest at runtime as 400 Bad Request ResponseError.
    Required handlingCaller MUST wrap in try-catch. Syntax errors are programming errors but manifest at runtime: try { const response = await client.esql.query({ query: 'FROM logs-* | WHERE @timestamp > NOW() - 1 hour | LIMIT 100' }); // Process response.rows or use helpers.esql() for transformation } catch (err) { if (err instanceof errors.ResponseError && err.meta.statusCode === 400) { // Syntax error or unknown column — check err.meta.body.error.reason console.error('ES|QL syntax error:', err.meta.body.error.reason); } else { throw err; } }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[15][1]
  • esql.query · esql-query-api-error
    error
    Whenesql.query() throws ResponseError with HTTP 403 when the authenticated user lacks read privileges for the queried indices. Connection failures throw ConnectionError or TimeoutError.
    Required handlingCaller MUST wrap in try-catch for all network and authorization failures: try { const response = await client.esql.query({ query: 'FROM my-index | LIMIT 10' }); } catch (err) { if (err instanceof errors.ResponseError) { if (err.meta.statusCode === 403) { // Missing read privilege for the queried index } } else if (err instanceof errors.ConnectionError) { // Network failure } throw err; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[15][1]
  • helpers.scrollSearch · helpers-scrollsearch-not-in-try-catch
    error
    Whenhelpers.scrollSearch() uses an async iterator. Errors thrown during iteration (connection failure, expired scroll context, auth error) propagate as exceptions inside the for-await-of loop body and will crash the caller if uncaught. Unlike scroll(), the helper automatically retries 429s — but not other errors.
    Required handlingWrap the entire for-await-of loop in try-catch: try { for await (const result of client.helpers.scrollSearch({ index: 'my-index', size: 100 })) { const documents = result.documents; // Auto-extracted hits // or: result.hits.hits for full hit objects } } catch (err) { if (err instanceof errors.ResponseError) { // Scroll context expired or search error } else if (err instanceof errors.ConnectionError) { // Network failure mid-scroll } throw err; }
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][16]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Source code
Other references

Research notes

Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.

Sources: @elastic/elasticsearch

All behavioral claims in contract.yaml are traced to the sources below.

Official Documentation

ClaimSource
All client methods throw on connection failure, timeout, or non-2xx responsehttps://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-connecting.html
Error types: ResponseError, ConnectionError, TimeoutError, NoLivingConnectionsError, RequestAbortedErrorhttps://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-connecting.html
ResponseError contains meta.statusCode, meta.body, meta.headershttps://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-connecting.html
bulk() Promise resolves even if individual items fail; check response.errorshttps://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-helpers.html
get() throws ResponseError 404 when document not found (v8 always throws, no ignore: [404])https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html
import { errors } from '@elastic/elasticsearch' for error type narrowinghttps://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-connecting.html

GitHub Repository

npm Package

Version Provenance

Versions found in test-repos/:

  • ^8.6.0test-repos/nextjs/examples/with-elasticsearch/package.json
  • ^7.13.0test-repos/backstage/plugins/search-backend-module-elasticsearch/package.json

Contract covers >=7.0.0 <9.0.0. Error handling semantics (try-catch requirement) are identical across v7 and v8. The main v8 change (response body unwrapping) is noted in contract notes but does not affect postcondition requirements.

Real-World Evidence

Pending real-world scan validation (Phase 7-8). Will be updated after scanning test repos.

Need a different package?
Request a profile