Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.synheart.ai/llms.txt

Use this file to discover all available pages before exploring further.

The behavior SDK has a small, mostly-quiet error surface. Most “failures” manifest as zero-valued metrics or empty event streams rather than thrown exceptions — by design, since the SDK is consent-gated and may run inside hosts that haven’t granted permissions yet.

Surfaces

SurfaceWhen
Synchronous exceptionAPI misuse before/around session boundaries.
null returned from a queryOptional state not available (e.g. getCurrentStats() outside a session).
Empty event streamPermissions denied or consentBehavior = false.
Silent drops at the runtime gateBehavior consent is not granted in the Synheart runtime.
Native channel errorsMethod-channel failures bubble as PlatformException (Dart) / typed errors (Kotlin/Swift).

Synchronous exceptions

The Dart SDK throws standard StateError / ArgumentError for misuse:
CauseException
startSession() before initialize()StateError("SynheartBehavior not initialized").
startSession() while another session is activeThe SDK rolls the previous session and starts a new one (no exception).
BehaviorSession.end() after the session has already endedReturns the cached summary; safe to call multiple times.
calculateMetricsForTimeRange with start > end or out of session boundsArgumentError.
dispose() followed by any further API callStateError("SynheartBehavior disposed").
The Kotlin SDK uses IllegalStateException and IllegalArgumentException; Swift uses Swift’s standard precondition failures with descriptive messages.

Permission failures

The SDK does not throw when a platform permission is missing. Instead:
PermissionBehavior when denied
Notification listener (Android)notification events do not flow. BehaviorSessionSummary.notificationSummary.notificationCount = 0.
Phone / call log (Android)call events do not flow. notificationSummary.callCount = 0.
AccelerometerMotion-lite stays unloaded; motionState = null in the summary. onMotionSample stream emits no samples.
Hosts query availability via:
  • checkNotificationPermission() / requestNotificationPermission() (Android).
  • checkCallPermission() / requestCallPermission() (Android).
iOS doesn’t have user-facing permissions for the surfaces the SDK uses; silent fallback is the same.

Native channel errors

Method-channel calls can fail if the native plugin isn’t registered (e.g. desktop builds without the platform layer). Dart’s PlatformException:
CodeCauseRecovery
MissingPluginExceptionNative side not registeredVerify plugin registration and platform-specific build steps.
INITIALIZATION_FAILEDNative init threwInspect details; usually a permissions or platform-version issue.
INVALID_CONFIGConfig field rejected by nativeValidate config; surface to developer.
Kotlin and Swift surface these as their own typed errors at the Kotlin / Swift bridge.

Motion classifier errors

When enableMotionLite = true and the bundled ONNX model fails to load:
  • The failure is logged with the underlying ORT error.
  • motionState stays null for the session.
  • getCurrentStats() does not include motion-state fields.
  • onEvent and other behavioral metrics continue normally.
The SDK does not retry model loading mid-session; restart the session (or initialize() after dispose()) to retry.

Runtime gate drops

When the host wires the SDK into synheart-core → the Synheart runtime, behavior events pass through the runtime’s consent gate. If Behavior consent is not granted, the runtime drops events at the engine seam silently. The SDK sees no error — events fire on onEvent, but the runtime never persists or aggregates them. This is intentional: SDK-side telemetry remains coherent (UIs still see live events) while the privacy boundary is enforced past the SDK.

Validation invariants

The SDK guarantees, regardless of error state:
  • Numeric metrics are always finite and within their declared range (NaN/inf clamped to 0.0).
  • BehaviorSessionSummary is always emitted on session.end(), even when no events flowed.
  • BehaviorEvent.eventId is unique within a session.
  • BehaviorEvent.timestamp is ISO-8601 UTC.
If any of these break, file a bug.