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
- Do NOT suppress and proceed — that wipes the host list. Route to a recovery UI that offers re-pairing.
- If the payload is corrupt, offer to reset 'orca:hosts' to [] after the user confirms, since hosts can be re-paired.
- Check device storage space and AsyncStorage health before retrying.
- 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
- Never proceed with a mutation over unreadable storage — it wipes paired hosts.
- Route to a recovery UI that offers re-pairing when storage is corrupt.
- Check AsyncStorage health and device storage space.
- Offer to reset 'orca:hosts' to [] only after the user confirms (hosts can be re-paired).
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
- pending host credential cleanup storage unreadable
- Host not found
- mobile relay host overlay storage unreadable
- [verify-linux-glibc-floor] objdump ${flag} failed for ${file
- Current manifest is missing ${name}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/53990aa1919aabd5.
Report an issue: GitHub.