GuidesError handling

Error handling

This guide covers the errors you may encounter when using FlushKit and the recommended way to handle each one.

SDK errors

StateError — double init

Calling FlushbarRemote.init a second time without first calling dispose throws a StateError:

code
StateError: FlushbarRemote is already initialised. Call dispose() first.

Fix: Ensure init is only called once. If you need to swap the API key at runtime, call dispose first:

dart
FlushbarRemote.dispose();
FlushbarRemote.init(apiKey: newKey, context: context);

Stream errors — connection failures

Network errors surface on the onError callback of the events stream. The SDK will retry automatically using exponential backoff — you do not need to reconnect manually.

dart
FlushbarRemote.events.stream.listen(
  (event) { /* ... */ },
  onError: (error) {
    // Log the error, but don't try to reconnect — the SDK handles it
    analytics.recordError(error);
  },
);

API errors

All REST API errors follow the same envelope:

json
{ "code": "ERROR_CODE", "message": "Human-readable description." }

UNAUTHORIZED (401)

Your API key is missing, malformed, or has been revoked.

json
{ "code": "UNAUTHORIZED", "message": "Invalid or missing API key." }

Fix: Check that you are including Authorization: Bearer fk_live_... in your request headers. If you recently rotated your key, update your server environment variable.

VALIDATION_ERROR (422)

A required field is missing or a value is out of range.

json
{ "code": "VALIDATION_ERROR", "message": "message is required." }

Fix: Check the POST /v1/notify reference for required fields and allowed values.

EVENT_LIMIT_REACHED (429)

Your project has exhausted its monthly notification quota.

json
{
  "code": "EVENT_LIMIT_REACHED",
  "limit": 1000,
  "used": 1000
}

Fix: Upgrade your plan from the billing page, or wait until the quota resets at the start of the next billing period.

PROJECT_LIMIT_REACHED (403)

Your plan only allows a limited number of projects.

json
{
  "code": "PROJECT_LIMIT_REACHED",
  "limit": 1,
  "current": 1
}

Fix: Upgrade to Starter or Growth plan for unlimited projects.

Handling errors in server code

A robust server-side notify function should handle the two quota errors gracefully:

ts
async function sendPushNotification(message: string) {
  const res = await fetch('https://api.flushkit.dev/v1/notify', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.FLUSHKIT_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ message }),
  })

  if (res.status === 429) {
    const body = await res.json()
    if (body.code === 'EVENT_LIMIT_REACHED') {
      // Soft failure — log and continue, don't crash
      console.warn(`FlushKit quota reached: ${body.used}/${body.limit}`)
      return
    }
  }

  if (!res.ok) {
    throw new Error(`FlushKit error ${res.status}`)
  }
}

Treat EVENT_LIMIT_REACHED as a soft failure in production. Crashing or blocking your main flow because a push notification couldn't be sent is usually worse than silently skipping it.