bug_capsule library

BugCapsule for Flutter: capture the context around a failure into a portable .bugcapsule capsule, and replay it locally with the bugcapsule CLI (dart run bug_capsule:bugcapsule).

One import gives the runtime and every integration; list the ones the app uses in BugCapsule.init(integrations: [...]).

Classes

AppInfo
AttemptAssessment
Baggage
bugcapsule-* entries of the W3C baggage header (monitoring-v1 §8).
BodyTap<T extends List<int>>
Passes a byte stream through unchanged while keeping its first limit bytes. Pause, resume and cancel reach the source; errors reach the listener. complete turns true when the source is done.
Breadcrumb types of monitoring-v1 §2.
BugCapsule
Entry point of the BugCapsule SDK.
BugCapsuleBackendConfig
Where capsules are uploaded and remote capture config comes from.
BugCapsuleBinding
The binding BugCapsule creates when an integration intercepts the default messenger: a WidgetsFlutterBinding whose messenger is wrapped before any plugin can use it.
BugCapsuleBloc
BugCapsuleConfig
BugCapsuleConnectionStatus
BugCapsuleDio
BugCapsuleEvent
One recorded event. t is milliseconds relative to the session anchor once the capsule is written; inside the recorder it is milliseconds since recording started.
BugCapsuleFeedbackForm
A ready-made user feedback form (monitoring-v1 §9): optional name and email, a required message. Submitting sends a feedback item through BugCapsule.captureFeedback, linked to eventId when given (e.g. BugCapsule.lastEventId() on an error screen).
BugCapsuleGetx
BugCapsuleGoRouter
BugCapsuleHttp
BugCapsuleInstrumentationStatus
Which replay instrumentation is set up. Connecting to the backend is not complete replay: these are the progressive setup steps.
BugCapsuleIntegration
Extension point for libraries the app uses.
BugCapsuleMobx
BugCapsuleNavigatorObserver
Screen transactions and navigation breadcrumbs for Navigator apps:
BugCapsuleNotifiers
BugCapsuleOverlay
QA capture button. Add it through MaterialApp.builder:
BugCapsulePlatformChannels
BugCapsuleRiverpod
BugCapsuleRiverpodState<T>
Serializer for the value of one provider (or every provider of a family) whose value type is T.
BugCapsuleSession
What the runtime exposes to integrations (BLoC, Dio, router, storage...).
BugCapsuleShakeToReport
"Shake to report": opens the feedback sheet when the device is shaken.
BugCapsuleSharedPreferences
BugCapsuleSpan
A timed operation in a trace (monitoring-v1 §8).
BugCapsuleState<B extends BlocBase<S>, S>
Serializer for the state of one BLoC/Cubit type B.
BugCapsuleStatus
Connection and instrumentation, for setup checks and support (BugCapsule.status).
BugCapsuleTestOverrides
Replaces the SDK's storage location, backend transport and sampling randomness in tests.
BugCapsuleTransaction
The root span of a trace segment: sent as one transaction item with its finished children.
BugCapsuleTransport
How the SDK talks to the backend. BugCapsuleBackendClient is the real one; tests substitute a fake.
BugCapsuleWebSocket
Capsule
CapsuleCodec
Reads and writes .bugcapsule files (gzip-compressed JSON). Reads spec v1 and v2; writes v2 only for capsules with interaction dependencies.
CapsuleDependency
One entry of manifest.dependencies (capsule-v2 §2).
CapsuleLimits
Structural validation of a decoded capsule document (spec v1 and v2).
CapsuleManifest
CapsuleMonitoring
manifest.monitoring = {eventId, traceId?, release, environment}.
CaptureResult
Result of writing a capsule.
Checkpoint
ConfigFetched
ConfigFetchFailed
ConfigFetchResult
Result of one GET /v1/sdk/config.
CrashCapsuleBuild
A crash capsule, encoded.
CrashCapsuleRequest
What the next launch knows about a crash it builds a capsule for.
CrashFailure
The crash a fatal native event reports, as a capsule failure.
CrashInfo
failure.crash of a crash capsule.
CrashJournal
Mirrors a FlightRecorder into a journal directory (see the library comment). Events are queued as they are recorded and handed to the sink at least every flushInterval, and at once on a checkpoint and on flush (a failure, going to the background).
CrashJournalLayout
CrashJournals
The journals of a storage directory.
DependencyGap
DependencyGaps
Gap codes of capsule-v2 §7.
DependencyKinds
manifest.dependencies[].kind.
DependencyStats
Per-dependency capture bookkeeping: gaps and stats for the manifest.
Divergence
DivergencePolicy
Separates divergences that are expected between a recording and a replay from those that make a "the failure did not happen" result meaningless.
Eligibility
EligibilityBuilder
Collects gaps from the core and from every integration.
EndpointRule
Per-endpoint normalization applied before a request key is computed.
EnvelopeCodec
The body of POST /v1/envelope, stored gzip-compressed in the outbox and sent with Content-Encoding: gzip.
EnvelopeItem
EnvelopeItemType
Envelope item types (monitoring-v1 §1).
EnvelopeResponse
Body of a 200 from /v1/envelope: {accepted, rejected: [{index, reason}]}. Rejected items are never retried.
EnvelopeTransport
Sends monitoring envelopes (POST /v1/envelope). BugCapsuleBackendClient implements it next to BugCapsuleTransport; tests substitute a fake.
ErrorEvent
An event item: an error or a message.
EventFrame
One stack frame. Frames are ordered oldest call first, crashing frame last.
EventHint
Extra information handed to beforeSend with an event.
EventTypes
Event types defined by capsule spec v1.
ExceptionValue
FailureRecord
A machine-checkable failure: the assertion replay and verify compare against.
FailureSignature
FixtureLookup
FixtureStore
Serves recorded responses in occurrence order per request key.
FlightRecorder
Bounded event buffer with checkpoints.
FlightRecorderListener
Told about what a FlightRecorder keeps, so a crash journal can mirror it on disk. Called synchronously from the recording path: implementations only hand the data on.
HttpBodies
Building blocks shared by HTTP client integrations (Dio, package:http): body decoding and encoding for http events, and the streaming helpers that keep a bounded prefix of a body without buffering it.
HttpFixture
One recorded HTTP exchange, as stored in an http event.
IdleCompressor
Decides when replay may jump over an idle stretch before an input.
InAppRules
Which Dart packages are app code (inApp). Defaults: the app's own package; dart: libraries and package:flutter/ are never app code.
InlineJournalSink
Writes on the calling isolate (tests, and the fallback when the writer isolate cannot start).
InteractionHost
Session-wide state shared by every interaction adapter: the payload budget and active-connection limit when capturing, the scheduler when replaying, and the remote kill switch.
InteractionIntegration
Base class of integrations that record replay dependencies (capsule-v2): WebSockets, platform channels and native SDK adapters.
InteractionLimits
Bounds of capsule-v2 §7.
InteractionPayload
A payload object (capsule-v2 §3).
InteractionScript
Replay of interaction dependencies (capsule-v2 §5), without timers: the runtime calls pump when nextDueAt arrives.
InteractionSession
Implemented by the runtime (and by test sessions): what interaction integrations need beyond BugCapsuleSession.
InteractionTypes
Event types of the interaction families (capsule-v2 §4).
InvalidConnectionToken
An unusable token, with an actionable message.
IsolateJournalSink
Writes in a background isolate: the UI isolate only hands the batch over.
JournalContents
Everything a journal holds.
JournalInfo
A journal's header and file times, read without its events.
JournalSink
Where CrashJournal hands its batches.
JournalWriter
Applies batches of journal operations to one journal directory with synchronous file I/O: in the writer isolate in apps, inline in tests.
Mechanism
How an error was caught (mechanism in monitoring-v1 §2).
MessengerInterceptor
An integration that decorates the binding's default messenger, so plugins registered on it are covered (the platform channel integration).
MissingDependency
MonitoringOptions
Monitoring (errors, release health, tracing, feedback; monitoring-v1): light, high-volume signals sent as envelopes next to capsules. Everything is redacted on the device with the capsule rules before it is queued.
MonitoringUser
NativeAdapter
Base class for adapters of third-party SDKs (Firebase, location, maps, payments): records the app-visible results of selected operations and, during replay, hands them back without calling the SDK (capsule-v2 §4.3). The real dependency is never contacted during replay, also not on a fixture miss.
NativeCrashEvent
One event from the native SDK, as monitoring-v1 event JSON.
NativeCrashReporter
Native crash capture for the hub; see the library comment.
NativeCrashSettings
What the hub asks a NativeCrashReporter to start with.
NativeCrashStart
What NativeCrashReporter.start found out right away.
ObservedCrash
The app under test died during an attempt (crash-capsules §4), as a runner or the CLI saw it.
OccurrenceCounter
Counts occurrences per key on the capture side.
OutboxLimits
Bounds on the upload outbox. Defaults: 10 capsules, 10 MiB in total, and 7 days of age; whichever is hit first evicts the oldest capsules.
ParsedConnectionToken
Result of parseConnectionToken.
ParsedStack
A parsed Dart stack trace.
PayloadBudget
Shared payload byte budget of every adapter in a session: a rolling window so a long session keeps recording recent traffic.
PayloadEncoder
Turns live values into payload objects: typed encoding, redaction, binary policy, size limits and the shared budget.
PlatformChannel
One allowlisted channel and the codec its messages use.
PlatformInfo
PrefetchedBody<T extends List<int>>
The first limit + 1 bytes of a request body, read before the request is sent so its key does not depend on whether (or how far) the transport reads the body. stream replays them followed by the rest, with pause, resume, cancel and errors forwarded.
PropagationTargets
tracePropagationTargets: plain strings match as substrings of the URL, /pattern/ strings as regular expressions.
RecordedInteraction
A recorded interaction event plus its scheduling metadata.
RecordedWindow
The checkpoint plus the events that follow it — what a capsule replays.
Redactor
On-device redaction applied before anything is recorded.
RemoteCaptureConfig
Capture config the backend can change at runtime (kill switch, sampling, bodies, redaction).
ReplayContext
ReplayInteractions
Replay of recorded interactions with timers: wraps an InteractionScript, arms a timer for the next due delivery and reports the script's divergences.
ReplayProtocol
HTTP protocol between the bugcapsule CLI (host) and an app in replay mode.
ReplayReport
ReplaySettings
RequestKeyBuilder
Builds the stable key used to match a replayed request to a recording.
RunEvaluation
RuntimeInfo
The runtime that captured a capsule (v1 extension, SDK 0.3+). Capsules written before it existed have no runtime; RuntimeInfo.infer derives one from the SDK name.
SamplingContext
What a tracesSampler decides on: the root transaction about to start.
Scope
Data applied to every event, transaction and feedback captured while it is current: user, tags, extras, contexts, level, fingerprint and the transaction bound to it (the current screen).
ScreenshotIntegration
Explicit diagnostic frames. The provider must mask secrets before returning PNG bytes; return null on sensitive screens. No automatic full-screen capture. Await capture() after rendering and before writing a capsule. Never call from a crash handler. Limits apply to the whole session, including evicted frames.
SessionInfo
ShakeDetector
Detects a shake in accelerometer samples (m/s², gravity included): at least minShakes samples above threshold g within window, then quiet for cooldown.
SpanStatus
Span statuses of monitoring-v1 §8.
TraceParent
A parsed traceparent header: 00-<traceId>-<parentSpanId>-<flags>.
TrackedStateIntegration
Base for state-management integrations without a global observer (ChangeNotifier, GetX, MobX stores): the app hands each state object to trackObject where it creates it.
TypedValue
Lossless JSON for the values platform channels and native SDKs exchange (capsule-v2 §3.1): integers vs doubles, byte and numeric arrays, and maps with non-string keys survive a round trip, so replay hands the app the same value it saw when capturing.
UploadResult
ValidConnectionToken
A usable token: backend is what BugCapsuleConfig.backend would be.

Enums

AttemptStatus
How one attempt counts toward the verdict.
BugCapsuleConnectionSource
How the backend was configured.
BugCapsuleConnectionState
Where the SDK stands with the backend (BugCapsule.status.connection.state).
CaptureMode
CheckpointKind
ConnectionTokenError
Why a connection token can't be used (spec/connection-token-v1.md).
DependencyCoverage
EligibilityStatus
EventLevel
FailureKind
crash (capsule format v2 only): the process died — a native signal or Mach exception, an ANR, a low-memory kill. Built on the next launch from the crash journal (see CrashJournal).
PayloadMode
PlatformChannelKind
ReplayOutcome
ReplayStrategy
How replay drives user input.
RunKind
replay expects the original failure; verify expects it gone.
UploadStatus
Verdict
What a batch of attempts proves. See evaluateRun for the rules.

Functions

assessAttempt(ReplayReport r) → AttemptAssessment
Classifies one attempt.
buildCrashCapsule(JournalContents journal, CrashCapsuleRequest request) → CrashCapsuleBuild?
Builds the crash capsule of journal (crash-capsules §2): the launch checkpoint when every event after it is on disk, else the newest periodic one; the periodic one too when the launch capsule is over maxCapsuleBytes. Null when there is no usable checkpoint, the capsule is still too big, or it would not validate.
canonicalJson(Object? value) → String
JSON with object keys sorted at every level; the input of stableHash for request and interaction keys.
crashCapsuleFrom(JournalContents journal, CrashCapsuleRequest request, Checkpoint checkpoint) → Capsule?
The capsule of journal from checkpoint (not encoded or size-checked).
cut(String s, int max) → String
debugIdFromBuildId(String hex) → String
GNU build id → debug id (monitoring-v1 §3): the first 16 bytes (zero padded), with the first three UUID fields byte-swapped (little-endian), formatted as a UUID — the same rule bugcapsule symbols upload applies to the .symbols file's build-id note.
debugIdFromBuildIdBytes(List<int> buildId) → String
evaluateRun(RunKind kind, int requestedAttempts, List<ReplayReport> reports) → RunEvaluation
The verdict rules, shared by bugcapsule run, bugcapsule verify and bugcapsule regress run. With N requested attempts, R reproductions, C clean attempts and I invalid ones:
interactionKey(String scope, String? method, Object? argsJson) → String
<scope>|<method>|<hash of canonical args> (capsule-v2 §5).
interactionScope(BugCapsuleEvent e, Map<String, String> callDirections) → (String, bool)?
The scheduling scope and direction of an interaction event (§5): the scope orders deliveries and is what an adapter binds a handler to.
isoTimestamp(DateTime t) → String
ISO-8601 in UTC with milliseconds (2026-10-21T14:03:10.982Z).
newSeed() → int
Random 32-bit seed for the session's deterministic Random.
newSpanId() → String
16 lowercase hex characters.
newTraceId() → String
32 lowercase hex characters.
parameterizePath(String path) → String
A path with id-like segments (numbers, hex runs of 8+, UUIDs) replaced by :id, and no query or fragment, for transaction and span names.
parseConnectionToken(String raw) → ParsedConnectionToken
Parses an SDK connection token (bcsdk.v1.<base64url JSON {api, key}>) offline. Never throws.
parseDartStack(String trace, {InAppRules rules = const InAppRules()}) → ParsedStack
Parses the VM (JIT and symbolic AOT), AOT non-symbolic (--split-debug-info, --obfuscate), Chrome/V8 and package:stack_trace terse formats. Unrecognised lines are skipped; asynchronous suspension markers are dropped.
rebaseOccurrences(List<BugCapsuleEvent> events) → List<BugCapsuleEvent>
Renumbers occurrence of keyed outbound interaction events from the start of events (capsule-v2 §5: occurrences count within the capsule).
resolveCrash(ReplayReport report, FailureRecord? expected) → ReplayReport
The attempt result for an app death (crash-capsules §4), given the capsule's expected failure. Reports without ReplayReport.crash, and reports where the expected failure had already fired, are unchanged.
sanitizeTags(Map<String, String> tags) → Map<String, String>
At most 50 tags with valid keys; values cut to 200 characters.
showBugCapsuleFeedback(BuildContext context, {String? eventId, bool? captureCapsule}) → Future<String?>
Shows BugCapsuleFeedbackForm in a modal bottom sheet. Completes with the feedback id, or null when cancelled (or monitoring is off).
stableHash(String input) → String
Two 32-bit FNV-1a passes with different offsets; 16 hex chars. Every SDK computes the same value (32-bit arithmetic keeps it portable to JS).
uuidV4() → String
RFC 4122 version 4 UUID.
validateCapsuleDocument(Object? doc) → String?
Returns null when doc is a valid v1 or v2 document, otherwise <json path> <reason>. Does not check specVersion against the reader's version (the codec does that, with its own message).

Typedefs

BeforeBreadcrumbCallback = Breadcrumb? Function(Breadcrumb breadcrumb)
BeforeSendCallback = ErrorEvent? Function(ErrorEvent event, EventHint hint)
BeforeSendTransactionCallback = Map<String, Object?>? Function(Map<String, Object?> transaction)
Receives the transaction payload (monitoring-v1 §8) and returns it, possibly modified, or null to drop it.
TracesSampler = double? Function(SamplingContext context)
Returns the sample rate (0-1) for a new trace, or null to use tracesSampleRate.

Exceptions / Errors

CapsuleFormatException
NativeAdapterException
Failure of a native adapter operation, recorded as native.error and rethrown during replay unless the adapter rebuilds its own exception.