tinyhumansai/openhuman · error

Failed to secure recovery phrase. Please try again.

Error message

Failed to secure recovery phrase. Please try again.

What it means

Later in setupLocalWalletFromMnemonic(): the phrase was accepted and the renderer asks the core to encrypt it via openhumanEncryptSecret(normalizedMnemonic). The call returns an object whose result should be a trimmed non-empty ciphertext; if it comes back empty/undefined the flow throws 'Failed to secure recovery phrase. Please try again.' — i.e. the core-side encryption step failed silently.

Solutions

  1. Retry once — transient keychain locks (especially right after login on macOS) can clear; the message itself says 'Please try again'.
  2. Check OS keychain/secret-service health: on Linux ensure gnome-keyring or kwallet is running; on macOS unlock the login keychain; on Windows check Credential Manager permissions.
  3. Verify core and app versions match (partial updates can skew RPC response shapes) — update or restart both.
  4. Inspect core logs for the encrypt-secret handler's error to find the underlying keyring failure; enable the keyring consent flow if prompted.

Example fix

// before
const encryptedMnemonic = (await openhumanEncryptSecret(normalizedMnemonic)).result?.trim();
if (!encryptedMnemonic) throw new Error('Failed to secure recovery phrase. Please try again.');

// after — retry once before failing
let encryptedMnemonic: string | undefined;
for (let attempt = 0; attempt < 2 && !encryptedMnemonic; attempt++) {
  encryptedMnemonic = (await openhumanEncryptSecret(normalizedMnemonic)).result?.trim();
}
if (!encryptedMnemonic) throw new Error('Failed to secure recovery phrase. Please try again.');
Defensive patterns

Strategy: retry

Try / catch

try {
  await setupLocalWalletFromMnemonic(args);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Failed to secure recovery phrase')) {
    // keychain may be transiently locked — prompt retry once
    if (await askUserToRetry()) return setupLocalWalletFromMnemonic(args);
  }
  throw err;
}

Prevention

When it happens

Trigger: The openhumanEncryptSecret RPC resolves but with an empty result: core keyring/encryption unavailable (OS keychain locked or denied), an error payload swallowed by the RPC wrapper, or a core version whose encrypt-secret response shape differs (result field renamed) so .result?.trim() yields undefined.

Common situations: OS keychain access denied (macOS Keychain, Windows Credential Manager, Linux secret service absent in minimal WMs) so the core cannot create the encryption key; core/renderer version skew after a partial update; headless/Linux environments without a secrets service where the keyring backend fails.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/5bd1ee1570a1b081. Report an issue: GitHub.

Appendix: source

Thrown at app/src/features/wallet/setupLocalWalletFromMnemonic.ts:28

  mnemonic: string;
  source: WalletSetupSource;
  setEncryptionKey: (value: string | null) => Promise<void>;
  /**
   * Set to `true` only when the user has explicitly confirmed wallet replacement
   * through the double-confirmation dialog. Defaults to `false`.
   */
  force?: boolean;
}): Promise<void> {
  const { mnemonic, source, setEncryptionKey, force } = args;
  const words = mnemonic.trim().split(/\s+/).filter(Boolean);
  if (words.length === 0) {
    throw new Error('Recovery phrase is required.');
  }
  const normalizedMnemonic = words.join(' ');
  const aesKey = deriveAesKeyFromMnemonic(normalizedMnemonic);
  const encryptedMnemonic = (await openhumanEncryptSecret(normalizedMnemonic)).result?.trim();
  if (!encryptedMnemonic) {
    throw new Error('Failed to secure recovery phrase. Please try again.');
  }

  await setEncryptionKey(aesKey);
  await setupLocalWallet({
    consentGranted: true,
    source,
    mnemonicWordCount: words.length,
    encryptedMnemonic,
    accounts: deriveWalletAccountsFromMnemonic(normalizedMnemonic),
    force,
  });
}

View on GitHub (pinned to 7491200858)