VoidhashDocs
DevelopersHelp centerGuidesAPI reference
Dashboard
Get started
Introduction
Quickstart
How Voidhash works
Glossary
Versions and releases
Concepts
Teams, projects and environments
API keys
Products and perks
Offers
Subscription lifecycle
People and identity
Events
Features
Paywalls in your app
Feature flags and A/B tests
Paywall components
Push notifications
Ad attribution in your app
Client SDKs
React Native
Swift
Kotlin
Web
Your backend
Node.js
PHP
Go
Rust
Other languages
Payment sources
Forward store notifications
Developer tools
CLI
MCP server
Query analytics with VoidQL
Web SDK
Web quickstart
Script tag
Identify users
Evaluate feature flags
Track
Track events
Page views and attribution
Privacy
Privacy and consent
Browser storage
Connect a consent tool
Keep data out of analytics
Revenue and attribution
Sell on the web
Stripe revenue
Web-to-app handoff
Delivery
First-party proxy
Tracking domain
Reference
Web SDK reference
Errors
Troubleshooting

Errors

Error classes, operation codes and diagnostics of the Web SDK, with what to do for each.

The Web SDK rejects with VoidhashError subclasses, and only for programmer errors and operations that failed outright. The network never makes a method reject: events and identity writes are queued and retried, and problems arrive as diagnostics.

Handle errors

Branch on the class with instanceof. A failed operation's message starts with a stable code, such as FAILED_TO_IDENTIFY.

import { VoidhashInvalidArgumentError, VoidhashNotInitializedError } from "@voidhash/web";

try {
  await voidhash.identify("user_123");
} catch (error) {
  if (error instanceof VoidhashInvalidArgumentError) {
    // The ID is blank or anonymous. Nothing changed.
  } else if (error instanceof VoidhashNotInitializedError) {
    // Call initialize() first.
  } else {
    reportError(error); // A VoidhashError whose message starts with FAILED_TO_IDENTIFY.
  }
}

Background work, such as a scheduled flush, reports through diagnostics and the client's error event instead.

Error types

All are exported from @voidhash/web and extend VoidhashError.

ClassRaised when
VoidhashConfigurationErrorcreateVoidhashClient got an invalid option.
VoidhashInvalidArgumentErrorA method got an argument it can't use. Nothing was changed or sent.
VoidhashNotInitializedErrorA method ran before initialize().
VoidhashDestroyedErrorA method ran after destroy().
VoidhashFeatureFlagsErroruseFeatureFlags() sets it as error when loading flags failed with a value that isn't an Error.
VoidhashErrorAn operation failed. The message starts with its code, and cause holds the original error.

Error codes

The code column holds the class for programmer errors, and the message prefix for failed operations. The Web SDK sells no products and presents no paywalls, so it has no purchase or paywall codes; Stripe reports checkout errors (see Checkouts).

Configuration

CodeWhenWhat to do
VoidhashConfigurationErrorAn option is invalid: no publishableKey, a secret key (vh_sk_...), a relative baseUrl, an unknown analyticsConsent, or a number that isn't a positive integer.Fix the option. Rotate a secret key that reached the browser.
VoidhashNotInitializedErrorA method ran before initialize() was called. Calls made while it runs wait for it.Call initialize() first, or use the provider.
VoidhashDestroyedErrorThe client was destroyed, for example by a provider that unmounted.Create a new client.
initialize() needs a browserinitialize() ran on a server.Call it from client-side code, such as an effect, or render the provider.
FAILED_TO_INITIALIZEinitialize() couldn't load saved state, for example because storage is blocked.Call initialize() again; with the provider, use retryInit().
useVoidhash must be used within a VoidhashProviderA hook rendered outside the provider.Wrap the tree in VoidhashProvider.
FAILED_TO_SET_ANALYTICS_CONSENTsetAnalyticsConsent() got a value other than granted, denied or pending, or couldn't apply it.Pass a valid value.

Identity

CodeWhenWhat to do
VoidhashInvalidArgumentErroridentify() got a blank user ID or one starting with vh_anon_ or vh:anon:, or track() a blank event name.Fix the call.
FAILED_TO_IDENTIFYidentify() couldn't switch the identity on the device.Report the error.
FAILED_TO_SIGN_OUT, FAILED_TO_RESETsignOut() or reset() failed.Retry.
FAILED_TO_SET_PERSON_ATTRIBUTESsetPersonAttributes() couldn't queue the update.Retry.
FAILED_TO_SET_PERSON_ATTRIBUTES_SYNCsetPersonAttributesSync() didn't get Voidhash's answer, or Voidhash refused the write.Retry, or use setPersonAttributes(), which queues.
FAILED_TO_SET_AD_DATA_SHARINGsetAdDataSharing() couldn't record the choice.Retry.
FAILED_TO_GET_FEATURE_FLAGS, FAILED_TO_REFRESH_FEATURE_FLAGSFlags couldn't be read or refreshed.Use your defaults.
FAILED_TO_TRACKtrack() or page() couldn't queue the event.Report the error.
FAILED_TO_FLUSH_ANALYTICS, FAILED_TO_FLUSH_IDENTITYflushAnalytics() failed outright. Transport failures resolve with pending instead.Nothing. What's queued stays queued.

Diagnostics

Diagnostics report problems the SDK handled itself, including an unreachable Voidhash (TRANSPORT_FAILED, CIRCUIT_OPENED) and a rejected publishable key (AUTHENTICATION_FAILED). Receive them with the onDiagnostic option or client.onDiagnostic(handler):

import { createVoidhashClient } from "@voidhash/web";

const voidhash = createVoidhashClient({
  onDiagnostic: (diagnostic) => console.debug("[voidhash]", diagnostic),
  publishableKey: "vh_pk_...",
});

Each diagnostic has a stable code, a kind for routing, the SDK operation, whether the SDK will retry (retryable), the httpStatus when there was a response, and a readable message.

CodeKindMeaning
TRANSPORT_FAILEDtransportA request failed or timed out. Events and identity writes are retried.
ANALYTICS_UNEXPECTED_STATUStransportVoidhash answered with an unexpected status. The batch stays queued.
MALFORMED_CAPTURE_RESPONSEtransportVoidhash accepted a batch but its answer couldn't be read.
KEEPALIVE_EVENT_TOO_LARGEtransportAn event didn't fit the request sent while leaving the page. It's sent on the next visit.
KEEPALIVE_UNCONFIRMEDtransportA closed page sent events while leaving and couldn't see the answer. They count as delivered.
IDENTITY_WRITE_REFUSEDtransportVoidhash refused an identity link or a setAdDataSharing(false) for good. It was dropped; the browser keeps its identity.
IDENTITY_WRITE_DROPPEDevictionMore than 20 users identified while Voidhash couldn't be reached; the oldest link was dropped.
ANALYTICS_EVENT_DROPPEDevictionEvents were dropped: the queue was full, Voidhash refused them for good, or the page closed with events kept in memory past the storage budget. A full queue reports once a minute.
BEFORE_SEND_FAILEDevictionanalytics.beforeSend threw or returned something other than an event or null, so the event was dropped.
SANITIZE_URL_FAILEDevictionanalytics.sanitizeUrl threw, so the address wasn't recorded.
AD_DATA_SHARING_REVOCATION_DROPPEDevictionA setAdDataSharing(false) was dropped: Voidhash had no such person for 48 hours, or more than 20 were waiting.
CIRCUIT_OPENEDbreakerFive requests in a row failed, timed out, or got a 408, 425, 5xx or an error page not from Voidhash, so requests pause. They resume on their own.
CIRCUIT_OPENbreakerA request was skipped while requests are paused.
AUTHENTICATION_FAILEDauthThe publishable key was rejected. Requests pause until initialize(), identify(), signOut() or reset(); otherwise one request retries the key once a minute.
SHARED_ID_COOKIE_REFUSEDcacheThe browser refused the crossSubdomainIdentity cookie, so the anonymous ID isn't shared. Reported once per client.
CACHE_READ_FAILEDcacheA stored value couldn't be read, for example because it was changed by hand. It was discarded.
CACHE_WRITE_FAILEDcacheBrowser storage refused a write, for example when full. The rest waits in memory.
ANALYTICS_QUEUE_IN_MEMORYcacheThe queue reached its share of browser storage during an outage. Its oldest events wait in memory and are lost if the page closes first.
ANALYTICS_CONSENT_DENIEDconsentAnalytics consent isn't granted, so analytics aren't recorded. Reported once.

Report auth diagnostics to your monitoring: they mean no data reaches Voidhash. When beforeSend or sanitizeUrl throws, the client's error event carries what it threw.

Next steps

  • Troubleshooting by symptom.
  • Web SDK reference.
  • Error codes across platforms.

Something wrong or missing on this page? Tell us by email or on Discord.

PreviousWeb SDK referenceNextTroubleshooting

On this page

Handle errorsError typesError codesConfigurationIdentityDiagnosticsNext steps