algoliasearch
>=4.0.0 <6.0.0postconditions26functions25last verified2026-06-24coverage score89%Postconditions: what we check
- search · search-no-try-catcherrorWhensearch() / searchSingleIndex() called in async context without surrounding try/catch. Any network failure, invalid API key (401), missing index (404), or rate limit (429) results in an unhandled rejected Promise.Throws
ApiError (status 401/403/404/429) — thrown immediately, not retried. RetryError — thrown when all Algolia hosts are unreachable.Required handlingCaller MUST wrap search calls in try/catch. Handle at minimum: - ApiError for API-level failures (check err.status or err.name === 'ApiError') - RetryError / network errors for connectivity failures Return a sensible empty result or error response — do NOT crash the request.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - searchSingleIndex · searchsingleindex-no-try-catcherrorWhensearchSingleIndex() called without surrounding try/catch.Throws
ApiError on 4xx responses. RetryError when all hosts unreachable.Required handlingCaller MUST wrap in try/catch. Same handling as search().costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - saveObject · saveobject-no-try-catcherrorWhensaveObject() called without surrounding try/catch. Indexing failure (invalid API key, insufficient write ACL, malformed record) is silently swallowed.Throws
ApiError — 401 (invalid key), 403 (missing write ACL), 400 (malformed record). RetryError — network failure.Required handlingCaller MUST wrap in try/catch. Indexing failures in production apps (webhooks, API routes, background jobs) must be logged and optionally retried. Silent failures cause search index to diverge from source of truth.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - saveObjects · saveobjects-no-try-catcherrorWhensaveObjects() called without surrounding try/catch. Batch indexing failure results in entire batch failing silently.Throws
ApiError — 401, 403, 400 (malformed records), 413 (request too large). RetryError — network failure.Required handlingCaller MUST wrap in try/catch. For large batches, log the failure with batch size for debugging. Consider splitting large batches if 413 errors occur.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - getObject · getobject-no-try-catcherrorWhengetObject() called without surrounding try/catch. Object not found (404) crashes the caller.Throws
ApiError with status 404 when object does not exist. ApiError with status 401/403 for auth failures. RetryError for network failures.Required handlingCaller MUST wrap in try/catch. Handle 404 explicitly — the object may have been deleted. Return null or a sensible default rather than crashing.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - getObjects · getobjects-no-try-catcherrorWhengetObjects() called without surrounding try/catch. Auth failure or network error crashes the caller.Throws
ApiError on auth failures (401/403). RetryError on network failures.Required handlingCaller MUST wrap in try/catch. Note: missing individual objects return null results, not errors. But API/network errors still throw.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - deleteObject · deleteobject-no-try-catcherrorWhendeleteObject() called without surrounding try/catch. Auth or network failure silently fails, leaving stale data in the search index.Throws
ApiError on auth failures (401/403) or invalid index (400). RetryError on network failures.Required handlingCaller MUST wrap in try/catch. Unhandled delete failures leave stale records in the search index, causing deleted items to appear in search results.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - deleteObjects · deleteobjects-no-try-catcherrorWhendeleteObjects() called without surrounding try/catch.Throws
ApiError on auth failures (401/403). RetryError on network failures.Required handlingCaller MUST wrap in try/catch. Failed batch deletes leave stale records in index.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - waitForTask · waitfortask-no-try-catcherrorWhenwaitForTask() called without surrounding try/catch.Throws
ApiError — task failed or polling encountered an error. RetryError — network failure during polling.Required handlingCaller MUST wrap in try/catch. Task failures mean data was not indexed. Log task ID for debugging.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - setSettings · setsettings-no-try-catcherrorWhensetSettings() called without surrounding try/catch. Invalid settings or auth failure silently leaves index misconfigured.Throws
ApiError — 400 (invalid settings), 401/403 (auth), 422 (unprocessable entity). RetryError — network failure.Required handlingCaller MUST wrap in try/catch. Failed settings updates leave the index with incorrect search configuration.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - replaceAllObjects · replaceall-no-try-catcherrorWhenreplaceAllObjects() called without surrounding try/catch. Partial failure during the atomic swap may leave index in inconsistent state.Throws
ApiError — auth, invalid objects, rate limit. RetryError — network failure.Required handlingCaller MUST wrap in try/catch. This is a critical operation — partial failure can leave the index empty or in an inconsistent state.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - partialUpdateObject · partialupdateobject-no-try-catcherrorWhenpartialUpdateObject() or partialUpdateObjects() called without surrounding try/catch. Auth failure or network error crashes the caller. Common in update webhooks and background sync jobs.Throws
ApiError (status 401/403) — invalid or insufficient API key (missing addObject ACL). ApiError (status 400) — malformed attributesToUpdate payload. RetryError — all Algolia hosts unreachable.Required handlingCaller MUST wrap in try/catch. Missing addObject ACL returns 403 and will never succeed without a key rotation — log the error and alert, do not silently retry. Partial update failures leave search data stale (e.g. status field not updated after a payment event).costmediumin prodsilent failureusers seedegraded performancevisibilitysilentSources[2] - clearObjects · clearobjects-no-try-catcherrorWhenclearObjects() called without surrounding try/catch. Failure during a reindex pipeline leaves the index in an inconsistent state — records may be partially cleared or not cleared at all.Throws
ApiError (status 400) — bad request or invalid arguments. ApiError (status 402) — feature not enabled on the current Algolia plan. ApiError (status 403) — missing deleteIndex ACL on the API key. ApiError (status 404) — index does not exist. RetryError — all Algolia hosts unreachable during the operation.Required handlingCaller MUST wrap in try/catch. A 402 error indicates a plan limitation that will never succeed without a plan upgrade — do not retry. A 404 means the index was already deleted or never created. In reindex pipelines, failure here means the subsequent saveObjects() will add to stale data, not replace it.costmediumin prodsilent failureusers seedegraded performancevisibilitysilentSources[3] - searchForFacetValues · searchforfacetvalues-no-try-catcherrorWhensearchForFacetValues() called without surrounding try/catch. Auth failure or network error crashes the caller. Common in faceted search UIs where a failed autocomplete crashes the search page.Throws
ApiError (status 401/403) — invalid or insufficient API key (missing search ACL). ApiError (status 404) — index not found. RetryError — all Algolia hosts unreachable.Required handlingCaller MUST wrap in try/catch. Return empty array on failure rather than crashing — facet search failures should degrade gracefully (e.g. show no autocomplete suggestions rather than crashing the search UI).costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[4] - deleteBy · deleteby-no-try-catcherrorWhendeleteBy() called without surrounding try/catch. Empty or invalid filters cause an ApiError (the operation explicitly rejects empty filters). Network errors cause a RetryError.Throws
ApiError (status 400) — empty filters object passed; the API explicitly rejects empty filters to prevent accidental deletion of all records. ApiError (status 403) — missing deleteIndex ACL. RetryError — all Algolia hosts unreachable.Required handlingCaller MUST wrap in try/catch AND validate that filters are non-empty before calling. An empty deleteByParams object throws ApiError 400. This is a common bug when filter values come from user input or upstream data that can be empty.costhighin prodimmediate exceptionusers seelost datavisibilitysilentSources[5] - partialUpdateObjects · partialupdateobjects-no-try-catcherrorWhenpartialUpdateObjects() called without surrounding try/catch. Common in webhook handlers and background sync jobs that update many records (e.g. update search data after bulk database events). Auth failure, invalid payload, or rate limits cause all batches to fail silently.Throws
ApiError (status 400) — malformed attributesToUpdate payload. ApiError (status 402) — feature not enabled on the current Algolia plan. ApiError (status 403) — missing addObject ACL on the API key. ApiError (status 404) — index not found. RetryError — all Algolia hosts unreachable.Required handlingCaller MUST wrap in try/catch. For large batch updates, log the object count and batch size for debugging. If createIfNotExists=false is used, the response does not indicate how many objects were skipped — callers cannot distinguish "updated" from "silently skipped" without separate verification.costmediumin prodsilent failureusers seedegraded performancevisibilitysilentSources[6] - partialUpdateObjects · partialupdateobjects-silent-skip-on-missingwarningWhenpartialUpdateObjects() is called with createIfNotExists=false (or the default createIfNotExists=true is intended to update existing records only), but the objectIDs in the batch do not exist in the index. With createIfNotExists=false, missing objects are silently skipped — the response is a success (BatchResponse[]) with no indication that objects were not found. With createIfNotExists=true (default), missing objects are CREATED, which may also be unexpected if the intent was to update-only.Throws
Does not throw. Returns BatchResponse[] even when all objects were missing. No error, no per-object status in the response.Required handlingWhen updating specific records, verify their existence with getObject() or getObjects() before calling partialUpdateObjects() if missing-object silencing is unacceptable. Or use saveObjects() (which always creates/replaces) when object existence is uncertain. If using createIfNotExists=false for "update-only" semantics, log and monitor the case where no updates are expected but the call succeeds — silent skips are invisible.costmediumin prodsilent failureusers seedegraded performancevisibilitysilentSources[6] - addOrUpdateObject · addorupdateobject-no-try-catcherrorWhenaddOrUpdateObject() called without surrounding try/catch. Throws synchronous native Error if required parameters (indexName, objectID, body) are missing. Also throws ApiError on API failures and RetryError on network failures. Common in data synchronization flows where external data is mapped to Algolia records by a known objectID (e.g. database ID).Throws
Error (native, synchronous) — if indexName, objectID, or body is missing/falsy. ApiError (status 400) — malformed record body. ApiError (status 402) — feature not enabled on plan. ApiError (status 403) — missing addObject ACL on the API key. ApiError (status 404) — index not found. RetryError — all Algolia hosts unreachable.Required handlingCaller MUST wrap in try/catch. Handle both synchronous parameter validation errors (native Error) and asynchronous API errors (ApiError, RetryError). This method REPLACES the entire record — ensure the body contains all desired attributes, not just the ones being updated (use partialUpdateObject for partial updates).costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[7] - indexExists · indexexists-auth-network-throwerrorWhenindexExists() called without surrounding try/catch. Callers commonly omit try/catch because the method "returns a boolean" and feels safe. But 401 (invalid API key), 403 (missing search ACL), and RetryError (network failure) still throw — they are not caught internally. Only 404 is caught and converted to false. This is a common false-safety assumption.Throws
ApiError (status 401) — invalid API key. ApiError (status 403) — missing search ACL on the API key. RetryError — all Algolia hosts unreachable. Note: ApiError (status 404) is caught internally and returned as false.Required handlingCaller MUST wrap in try/catch even though the method returns a boolean. The 404 case is safe (returns false), but auth and network failures still throw: try { const exists = await client.indexExists({ indexName }); if (!exists) { // Index needs to be created } } catch (error) { if (error instanceof ApiError) { console.error('Auth or API error checking index:', error.status, error.message); } throw error; }costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[8] - waitForAppTask · waitforapptask-max-retries-exceedederrorWhenwaitForAppTask() called without surrounding try/catch. If the app-level task does not reach "published" status within maxRetries attempts (default 50 retries × up to 5000ms per retry = ~4 minutes total), throws an Error with "The maximum number of retries exceeded." This is a native Error, not an ApiError or RetryError. Also throws if getAppTask() polling encounters an API or network error.Throws
Error (native) — "The maximum number of retries exceeded. (50/50)" when polling exhausted without task completion. ApiError — if getAppTask() returns an API error during polling. RetryError — if all Algolia hosts unreachable during polling.Required handlingCaller MUST wrap in try/catch. Handle both the timeout Error and API errors: try { await client.waitForAppTask({ taskID: response.taskID }); } catch (error) { if (error.message?.includes('maximum number of retries')) { console.error('App task timed out — check Algolia dashboard:', taskID); } else if (error instanceof ApiError) { console.error('API error while waiting for task:', error.status); } throw error; } To extend the timeout, pass maxRetries or a custom timeout function: waitForAppTask({ taskID, maxRetries: 100 })costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[8] - saveObjectsWithTransformation · saveobjectswithtransformation-missing-regionerrorWhensaveObjectsWithTransformation() called when the Algoliasearch client was initialized WITHOUT the transformation.region option. This is a configuration error — the client must be initialized as: algoliasearch(appId, apiKey, { transformation: { region: 'eu' } }) Calling saveObjectsWithTransformation() on a client without transformation.region throws synchronously (before any network request). This is distinct from the normal SearchClient — only the full Algoliasearch client has this method.Throws
Error (native, synchronous) — "`transformation.region` must be provided at client instantiation before calling this method." or "`region` must be provided when leveraging the transformation pipeline".Required handlingEnsure the Algoliasearch client is initialized with transformation.region before calling this method. Wrap in try/catch to handle both configuration errors and Ingestion API (WatchResponse) errors from the pipeline: const client = algoliasearch(appId, apiKey, { transformation: { region: 'eu' } }); try { await client.saveObjectsWithTransformation({ indexName, objects }); } catch (error) { console.error('Transformation pipeline error:', error.message); throw error; }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[9] - batch · batch-no-try-catcherrorWhenbatch() called without surrounding try/catch. Auth failure, malformed batch payload, or rate limit causes the entire batch to fail. Common in custom indexing pipelines that bypass the saveObjects helper to control action ordering (e.g. mixed addObject + deleteObject sequences for atomic-ish reindex flows).Throws
ApiError (status 400) — malformed batch payload (invalid action, missing objectID for delete/partial update actions, payload exceeds Algolia size limits). ApiError (status 402) — feature not enabled on the current Algolia plan. ApiError (status 403) — missing addObject ACL on the API key. ApiError (status 404) — index not found. ApiError (status 429) — indexing rate limit exceeded. RetryError — all Algolia hosts unreachable.Required handlingCaller MUST wrap in try/catch. Unlike saveObjects/deleteObjects, batch() does NOT chunk — a single oversized request fails atomically. Log the action count and total payload size for debugging. 429 errors indicate the pipeline is exceeding indexing limits; back off and retry with exponential delay rather than re-firing immediately.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[10] - multipleBatch · multiplebatch-no-try-catcherrorWhenmultipleBatch() called without surrounding try/catch. Failure of the entire multi-index batch (auth failure, any single 404 for a missing target index, malformed request) leaves the caller with no record of which indices were partially written. Common in multi-tenant fan-out flows where a missing tenant index causes the entire batch to fail and ALL tenants lose the update, not just the missing one.Throws
ApiError (status 400) — malformed batch payload across any of the target indices. ApiError (status 402) — feature not enabled on the current Algolia plan. ApiError (status 403) — missing addObject ACL on the API key. ApiError (status 404) — at least one referenced index does not exist; the entire batch fails. ApiError (status 429) — indexing rate limit exceeded. RetryError — all Algolia hosts unreachable.Required handlingCaller MUST wrap in try/catch. On 404, identify which referenced index is missing (the error message includes the index name) and decide whether to create-on-the-fly or skip. On 429, consider splitting the batch into per-index calls so a single hot index doesn't block writes to cold indices. Log the full list of target indices on every failure — silent failure here means an entire fan-out of tenant indices silently diverged from source of truth.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[11] - browse · browse-no-try-catcherrorWhenbrowse() called without surrounding try/catch. Common in export and migration scripts that assume a long-running operation will complete cleanly. Auth failure (missing browse ACL on the key — distinct from search ACL) and network errors crash mid-export, leaving partial state. Cursor-driven pagination loops that don't handle errors leak into infinite loops or unhandled rejections.Throws
ApiError (status 400) — malformed browse parameters. ApiError (status 402) — feature not enabled on the current Algolia plan. ApiError (status 403) — missing browse ACL on the API key (distinct from search ACL). ApiError (status 404) — index not found. RetryError — all Algolia hosts unreachable.Required handlingCaller MUST wrap in try/catch. In paginated export loops, persist the last successful cursor to disk or state store so failed exports can resume rather than restart. Document the ACL requirement explicitly — a key with search but not browse will throw 403 at the first call, which is confusing if the developer assumed search-able implies browse-able.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[12] - browseObjects · browseobjects-no-try-catcherrorWhenbrowseObjects() called without surrounding try/catch. A single page failure (auth flake, transient 5xx, network drop) aborts the entire iteration. The user-supplied aggregator callback is invoked synchronously inside the iteration — if the callback throws, that throw propagates as the iteration's rejection, masking whatever progress the aggregator already made. Common in full-index export and reindex pipelines where the cost of a mid-export failure is a hung migration or partially-written destination.Throws
ApiError (status 400/402/403/404) — same conditions as browse(), but on ANY page of the iteration. A 403 on page 17 of an export looks identical to a 403 on page 1 from the caller's perspective. ApiError (status 429) — indexing/query rate limit exceeded mid-export. RetryError — all Algolia hosts unreachable during any page. User-thrown Error — anything the aggregator callback throws propagates out of browseObjects().Required handlingCaller MUST wrap in try/catch. For long-running exports, capture the last-seen cursor inside the aggregator so a failed iteration can resume from where it stopped rather than restart at page 1. Defensive: validate the aggregator does not throw on adversarial record shapes — a single malformed record can otherwise abort a 100k-record export.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[8] - operationIndex · operationindex-no-try-catcherrorWhenoperationIndex() called without surrounding try/catch. Common in blue/green index swap flows (build new-index, copy old-index settings/rules onto it, atomic swap). A failure mid-copy leaves the destination in a partial state — the destination's records may already be overwritten with zero rows from a missing source while settings remain from the previous contents. The follow-up waitForTask() call also needs error handling (covered by waitForTask postcondition) — but the initial operationIndex() throw is a distinct failure mode.Throws
ApiError (status 400) — invalid operation params, copying to a destination that already has replicas, or attempting to copy disallowed settings (enableReRanking, mode, replicas). ApiError (status 402) — feature not enabled on the current Algolia plan. ApiError (status 403) — missing addObject ACL on the API key. ApiError (status 404) — source index does not exist. ApiError (status 429) — indexing rate limit exceeded. RetryError — all Algolia hosts unreachable. Note: per Algolia docs, MOVE with a missing source index is ignored silently (no throw) — but COPY with a missing source creates an empty destination, which is a distinct silent failure surface the caller should validate after the operation.Required handlingCaller MUST wrap in try/catch. For blue/green swaps, validate the source index is non-empty BEFORE calling operationIndex(scope=copy) — Algolia silently treats a missing source as a 0-record copy. Always pair with waitForTask() and confirm taskID reached "published" before treating the destination as ready. On 400 errors, the error message includes which constraint was violated (replica conflict vs disallowed setting); log it for debugging.costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[13]
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
- [1]algolia.com/doc/api-client/advancedHandling Errors
- [2]algolia.com/doc/api-reference/api-methodsPartial Update Objects
- [3]algolia.com/doc/api-reference/api-methodsClear Index
- [4]algolia.com/doc/api-reference/api-methodsSearch For Facet Values
- [5]algolia.com/doc/api-reference/api-methodsDelete By
- [6]algolia.com/doc/rest-api/searchPartial Update Object
- [7]algolia.com/doc/rest-api/searchAdd Or Update Object
- [8]algolia.com/doc/libraries/javascriptSearch
- [9]algolia.com/doc/guides/sending-and-managing-dataPush
- [10]algolia.com/doc/rest-api/searchBatch
- [11]algolia.com/doc/rest-api/searchMultiple Batch
- [12]algolia.com/doc/rest-api/searchBrowse
- [13]algolia.com/doc/api-reference/api-methodsCopy Index
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources — algoliasearch
Official Documentation
-
Error Handling Guide: https://www.algolia.com/doc/api-client/advanced/handling-errors/ — Official guide on ApiError, RetryError, error status codes, and recommended handling patterns
-
API Client v5 Getting Started: https://www.algolia.com/doc/api-client/getting-started/install/javascript/ — Installation, basic usage, and v5 API overview
-
API Client v4 Reference — Search: https://www.algolia.com/doc/api-client/methods/search/ — v4 index.search() method documentation including error behavior
-
API Client v4 Reference — Indexing: https://www.algolia.com/doc/api-client/methods/indexing/ — v4 saveObject, saveObjects, deleteObject, deleteObjects documentation
-
v4 to v5 Migration Guide: https://www.algolia.com/doc/api-client/getting-started/upgrade-guides/javascript/ — Documents breaking changes including index-based → client-based API and error class changes
npm Package
- algoliasearch on npm: https://www.npmjs.com/package/algoliasearch — Version history, weekly downloads, README
GitHub Source
-
algoliasearch-client-javascript (monorepo): https://github.com/algolia/algoliasearch-client-javascript — Source code for both v4 and v5 clients
-
Error Classes (v5): https://github.com/algolia/algoliasearch-client-javascript/tree/main/packages/client-common/src/errors — ApiError, DetailedApiError, RetryError, DeserializationError class definitions
Error Status Code Reference
| Status | Error | Description |
|---|---|---|
| 400 | ApiError | Malformed request / invalid parameters |
| 401 | ApiError | Invalid API key |
| 403 | ApiError | API key lacks required ACL permissions |
| 404 | ApiError | Index or object not found |
| 422 | ApiError | Invalid settings / unprocessable entity |
| 429 | ApiError | Rate limit exceeded |
| RetryError | — | All Algolia hosts unreachable (network down or wrong appId) |
Version History
- v5.x (2024+): Rewritten client. Named export
{ algoliasearch }. NoinitIndex(). All methods on client directly. Error classes useinstanceof. - v4.x (2019-2024): Classic client. Default export.
client.initIndex(). Error objects (not class instances), checkerr.name. - v3.x and below: Deprecated. Do not use.
Real-World Usage Patterns
Algolia is primarily used for:
- Documentation search — via
react-instantsearch/@docsearch/react(search-only, client-side) - Product/content search — SaaS apps index products, blog posts, help articles
- Server-side indexing — webhooks, background jobs, API routes that keep Algolia in sync with database