stablyai/orca · error

Orca Relay pairing requires a native secret store

Error message

Orca Relay pairing requires a native secret store

What it means

Thrown by requireNativeSecretStore when Platform.OS === 'web'. The pairing journal persists secrets to a native keychain (iOS Keychain / Android Keystore) that does not exist on web; save and load are refused on web targets.

Source

Thrown at mobile/src/transport/mobile-relay-pairing-journal-store.ts:145

    const result = MobileRelayPairingJournalMetadataSchema.safeParse(JSON.parse(raw))
    return result.success ? result.data : null
  } catch {
    return null
  }
}

function parseSecrets(raw: string) {
  try {
    const result = MobileRelayPairingJournalSecretsSchema.safeParse(JSON.parse(raw))
    return result.success ? result.data : null
  } catch {
    return null
  }
}

function requireNativeSecretStore(): void {
  if (Platform.OS === 'web') {
    throw new Error('Orca Relay pairing requires a native secret store')
  }
}

/** Test-only: drain the module mutation chain between cases. */
export function resetMobileRelayPairingJournalStoreForTests(): void {
  journalMutation = Promise.resolve()
  resetPairingKeychainForTests()
}

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Guard the pairing flow behind a Platform.OS check at the caller and skip relay pairing on web.
  2. Use a platform-specific entry point so the journal store is not imported on web.
  3. Provide a web-appropriate credential path or surface 'relay pairing unavailable on web' in the UI.

Example fix

// before
import { saveMobileRelayPairingJournal } from './mobile-relay-pairing-journal-store'
await saveMobileRelayPairingJournal(journal) // throws on web
// after
import { Platform } from 'react-native'
if (Platform.OS === 'web') {
  throw new Error('relay pairing unavailable on this platform')
}
await saveMobileRelayPairingJournal(journal)
Defensive patterns

Strategy: validation

Validate before calling

import { Platform } from 'react-native'
function assertNotWeb(): void {
  if (Platform.OS === 'web') {
    throw new Error('relay pairing unavailable on web')
  }
}
// call assertNotWeb() before invoking save/load so the error is yours, not the store's

Type guard

import { Platform } from 'react-native'
function supportsNativeSecretStore(): boolean {
  return Platform.OS !== 'web'
}

Prevention

When it happens

Trigger: Calling saveMobileRelayPairingJournal or loadMobileRelayPairingJournal inside a web build (React Native Web / Expo web).

Common situations: Running the mobile transport module in a web target during development; importing the journal store on web via a shared entry point; SSR hitting the module.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/c6c2f14e9df0dbc1. Report an issue: GitHub.