Troubleshooting | Orwel Docs
Docs

Troubleshooting

Partial batches (HTTP 207), rejected or unknown event codes, and conversions that fail.

The fastest way to debug an install is to send traffic with the development key and open Dev mode: every request shows up live with the reason it failed and how to fix it. Add debug: true to orwel.init() to see the SDK logs in the browser console.

How the ingest answers

Endpoint Status Meaning
POST /ingest 200 The event was stored.
POST /ingest 400 The event was rejected. The body says why, for example Event not found: <code>.
POST /ingest/batch 200 Every event in the batch was stored.
POST /ingest/batch 207 Some events were stored and some were not. The refused events are in failedEvents.
POST /ingest/batch 400 The batch itself is invalid: bad JSON, missing batchId, count or events, count not equal to the number of events, more than 100 events, or a bad key. Nothing was stored.
POST /ingest/batch 500 No event in the batch could be stored.

A 207 body looks like this:

json
{
  "success": false,
  "error": "Some events failed to process",
  "code": "VALIDATION_ERROR",
  "details": {
    "processed": 9,
    "failed": 1,
    "batchId": "batch_1760000000000_k2j3h4",
    "failedEvents": [ { "type": "track", "code": "quote_sent", "...": "..." } ]
  }
}

The SDK does not retry rejected events, because resending an invalid event would loop forever. Since SDK 1.7.1 a 400 is logged in the console with the server response and the rejected codes before the events are discarded:

Batch rejected (400) - events DISCARDED, not retrying  { codes: [...], serverResponse: "..." }
Event rejected (400) - DISCARDED, not retrying          { code: "...", serverResponse: "..." }

A 207 counts as delivered for the SDK, so the events it refused are not logged in the console. Use Dev mode to see them.

Events rejected as unknown

Symptom: some track() calls never appear, the batch answers 207 (or 500 if every event failed), and Dev mode shows event_not_found.

Cause: the server only accepts track() codes that exist in your workspace catalog: the Orwel catalog plus the custom codes your workspace registered. Codes are not created on the fly.

Fix:

  1. Open Journeys setup or Features setup in the Development section, add the code to a journey or feature (from the catalog, or as a Custom event) and save. See Journeys and features setup.
  2. Or change your code to an existing catalog code.
  3. Check the Status tab: the code should move from "Not registered" to "Tested" once it arrives with the development key.

Conversions are not gated by the catalog, so this never affects conversion().

Events lost on large flushes (SDK before 1.7.1)

Symptom: pages that fire many events (long sessions, heavy auto detection) lose whole blocks of events, with nothing in the console and nothing on the server.

Cause: before 1.7.1 the SDK posted the whole queue (up to 1000 events) in one batch. The server caps a batch at 100 events and answers 400, and older SDKs treated that 400 as "do not retry" without logging anything.

Fix: update the SDK. 1.7.1 sends the queue in chunks of 100.

bash
npm i orwel@latest

A conversion fails or never shows up

conversion() is async and resolves with the real outcome. Read it:

ts
const { success, reason } = await orwel.conversion('demo_request', { email })
if (!success) console.warn('Orwel conversion failed:', reason)
reason What happened Fix
visitor_unresolved The visitor id did not resolve within 5 seconds, so the conversion was not sent (it would have arrived with no visitor). Make sure orwel.init() runs early on every page, before the form can be submitted, and that requests to api.orwel.io are not blocked (ad blockers, a strict Content Security Policy).
delivery_failed The request was sent but the server did not acknowledge it (network error, timeout, or a rejection). Check the console with debug: true and the request in Dev mode.
error Something threw inside the SDK. Check the console with debug: true.

If conversion() throws instead of resolving, the input is invalid: the code is not snake_case, the properties are not an object, or an email field is not a valid address.

The conversion arrives but the lead looks wrong

Symptom Cause Fix
No notification email, lead not enriched No email (or phone) in the conversion properties or a previous identify(). Pass email in the conversion properties.
The lead shows as direct or organic The landing URL had no UTMs or ad click ids. Tag your ads and links (see Attribution). Test with ?utm_source=test.
Two leads for one submit SDK before 1.6 had no conversionId, so retries were not deduplicated exactly. Update the SDK.
The conversion is missing after a successful submit and a form_abandon appears instead The form was unmounted before the conversion was sent, or orwel.form() with trackAbandon saw the form disappear. await orwel.conversion() before showing the success state, and do not combine orwel.form() with a manual conversion on the same form.
The lead has a Dev badge and no integrations ran It was sent with the development key. Expected. Use the production API key in production.

init() throws

  • apiKey must start with "orwel_" or appears to be invalid (too short): the environment variable is empty or wrong. Check the variable name for your framework (for example NEXT_PUBLIC_ORWEL_KEY, PUBLIC_ORWEL_KEY, VITE_ORWEL_KEY).
  • config must be an object: call orwel.init({ apiKey }), not orwel.init(apiKey).

API and MCP

  • 401 with a public or development key: those keys only send data. Create an API key (orwel_sk_) to read.
  • 403 from a browser: the page's origin is not in the key's allowed origins, or the key is server only.
  • 403 plan_not_allowed on /mcp: the workspace has no active subscription.