stablyai/orca · error · Error

host list storage unreadable

Error message

host list storage unreadable

What it means

readStoredHostProfilesForMutation could not load a usable host list from AsyncStorage (key 'orca:hosts'). The function tries loadStoredHostProfiles and throws only if parsing returns null (corrupt/non-array payload) or the AsyncStorage read itself throws. This is a fail-closed guard: mutations (save/remove/rename) must not proceed over unreadable storage because a blind write could wipe all paired hosts.

Source

Thrown at mobile/src/transport/host-metadata-store.ts:19

import AsyncStorage from '@react-native-async-storage/async-storage'
import { StoredHostProfileSchema, type HostProfile, type StoredHostProfile } from './types'

const STORAGE_KEY = 'orca:hosts'

export async function loadStoredHostProfiles(): Promise<StoredHostProfile[] | null> {
  return parseStoredHostProfiles(await AsyncStorage.getItem(STORAGE_KEY))
}

export async function readStoredHostProfilesForMutation(): Promise<StoredHostProfile[]> {
  try {
    const parsed = await loadStoredHostProfiles()
    if (parsed) {
      return parsed
    }
  } catch {
    // Normalize storage and payload failures for fail-closed mutations.
  }
  throw new Error('host list storage unreadable')
}

export function writeStoredHostProfiles(hosts: readonly StoredHostProfile[]): Promise<void> {
  return AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(hosts))
}

export function toStoredHostProfile(host: HostProfile): StoredHostProfile {
  const { id, name, endpoint, publicKeyB64, lastConnected } = host
  return { id, name, endpoint, publicKeyB64, lastConnected }
}

function parseStoredHostProfiles(raw: string | null): StoredHostProfile[] | null {
  if (!raw) {
    return []
  }
  try {
    const parsed = JSON.parse(raw) as unknown
    if (!Array.isArray(parsed)) {

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Do NOT suppress and proceed — that wipes the host list. Route to a recovery UI that offers re-pairing.
  2. If the payload is corrupt, offer to reset 'orca:hosts' to [] after the user confirms, since hosts can be re-paired.
  3. Check device storage space and AsyncStorage health before retrying.
  4. Ensure at least one host record passes StoredHostProfileSchema (pre-0.0.3 records with deviceToken are intentionally filtered).
Defensive patterns

Strategy: validation

Validate before calling

async function canReadHostList(): Promise<boolean> {
  try {
    const hosts = await loadStoredHostProfiles()
    return hosts !== null
  } catch {
    return false
  }
}

// Check before mutations
if (!(await canReadHostList())) {
  showStorageRecoveryUI()
}

Try / catch

try {
  await saveHost(host)
} catch (e) {
  if (e.message === 'host list storage unreadable') {
    showStorageRecoveryUI()
  }
}

Prevention

When it happens

Trigger: AsyncStorage.getItem throws (native I/O failure); parseStoredHostProfiles returns null because JSON.parse failed or the top-level value is not an array; the stored payload is valid JSON but all entries failed StoredHostProfileSchema validation (all pre-v0.0.3 records with deviceToken).

Common situations: App crashed mid-write leaving truncated JSON; all stored host records are from a pre-v0.0.3 format that embedded deviceToken (filtered out, yielding null only if the entire array was dropped); AsyncStorage corruption after OS update; test environment without proper AsyncStorage.

Related errors


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