Skip to content
TraceItX Docs
Documentation

Errors & limits

One page for "why was this rejected" and "how big can that be".

Updated

Limits

Ingest

LimitValue
Total request size25 MB
Decompressed envelope5 MB
Attachments per report5
Single attachment25 MiB — in practice the total cap trips first
Rate limit, per SDK key60 / minute, when enabled
Rate limit, per source IP200 / minute, when enabled

Envelope content

FieldCap
reporter.title50 characters
reporter.description600 in the protocol, 400 at ingest
payload.extra2 000 characters
payload.breadcrumbs128 entries
Breadcrumb byte budget16 KB by default; the server may raise it, up to 64 KB
Console entries100. console.maxEntries on React and Web changes it; the native ringBufferCapacity field is currently not read.
Network entries100 (configurable)

Caps are enforced by truncation at the SDK, not by rejection — a report that would exceed a cap ships trimmed, with a trim marker in the breadcrumb chain, rather than failing. payload.extra is truncated silently at the setExtra call site.

reporter.description is the one to know about. The protocol allows 600 characters and ingest clips to 400, so a description between the two is accepted and arrives 200 characters shorter than the user typed. Cap your own input at 400 if you surface a counter.

Typical sizes

A median envelope is about 84 KB, mostly the screenshot. Console and network entries are deltas from a rolling buffer and the breadcrumb chain is capped, so size scales with the screenshot far more than with session length.

Error codes

Ingest

StatusErrorRetry?What to do
400schema_validation_failednoThe envelope did not match the schema, or carried an unknown top-level key. details lists the failing paths.
400envelope_too_largenoThe decompressed envelope exceeded 5 MB. 400, not 413.
400attachment_missingnoThe envelope names a partName that was not uploaded.
400attachment_unexpectednoA part was uploaded that the envelope does not reference.
400envelope_part_missingnoNo envelope part in the multipart body.
400envelope_invalid_jsonnoThe envelope part was not valid JSON, or could not be gunzipped.
400no_partsnoThe request carried no parts at all.
400sha256_mismatch / bytelength_mismatchnoA part did not match the hash or length declared for it.
400attachment_sha256_mismatchnoAn attachment’s bytes did not hash to its declared sha256.
413attachment_too_largenoOne attachment exceeded 25 MiB.
401invalid_sdk_keynoCheck the key and that the app still exists.
403org_suspendednoIngestion is suspended: the organisation exceeded its plan’s monthly active install limit for two complete months and is over again. Upgrade, or finish a month within the limit. The body carries reason (over_allowance) and since (a date). Rejected reports are not stored.
413payload_too_largenoThe whole request exceeded 25 MB. Drop or downscale the screenshot.
429rate_limit_exceededyesBack off; honour Retry-After.

Ticket API

See Ticket API for its own codes — it uses a different credential and a different error vocabulary.

SDK errors

Capture failures never become your crash: the SDKs swallow internal errors rather than propagating them out of a capture path.

That is not the same as “nothing throws”. iOS start(config:) is throws and report.open() is async throws, and Android’s start validates its config — those are public calls that report a problem to you deliberately, and you should handle them.

On React you can see those failures, via onError and debug:

<TraceItXProvider config={{
  apiKey: 'txx_live_…',
  debug: true,
  onError: (err) => console.warn('[traceitx]', err.name, err.message),
}}>

Both exist on React and Web only. The native and React Native SDKs expose neither: on iOS and Android, captureGate and currentConfig show what the SDK thinks its state is; otherwise read the platform log.

If reports are not arriving, the usual causes are a wrong key, a provider or start() call that does not run on the path you think it does, and — on the web — a strict CSP with no cspNonce. See your SDK’s Configuration page.