tinyhumansai/openhuman · error
Recovery phrase is required.
Error message
Recovery phrase is required.
What it means
setupLocalWalletFromMnemonic() drives local-wallet creation from a user-entered recovery phrase. After trimming and whitespace-splitting the mnemonic, if zero words remain it throws 'Recovery phrase is required.' — pure input validation before any crypto derivation (deriveAesKeyFromMnemonic, openhumanEncryptSecret) or RPC runs.
Solutions
- Disable the submit/continue button until words.length >= 12 (standard BIP-39 length) so the error is unreachable.
- Validate in the UI: trim input, count words, show inline 'enter your recovery phrase' feedback before calling the setup function.
- If importing programmatically, assert the mnemonic is a non-empty string before invoking.
- Check the form component for accidental state resets between screen steps.
Example fix
// before
const canSubmit = true; // always enabled
await setupLocalWalletFromMnemonic({ mnemonic, ... });
// after
const words = mnemonic.trim().split(/\s+/).filter(Boolean);
const canSubmit = words.length === 12 || words.length === 24;
if (!canSubmit) return setFormError('Enter your full recovery phrase.');
await setupLocalWalletFromMnemonic({ mnemonic, ... }); Defensive patterns
Strategy: validation
Validate before calling
const words = mnemonic.trim().split(/\s+/).filter(Boolean);
if (words.length < 12) {
return setFormError('Enter your full recovery phrase (12 or 24 words).');
} Type guard
function isNonEmptyMnemonic(v: string): boolean {
return v.trim().split(/\s+/).filter(Boolean).length >= 12;
} Try / catch
try {
await setupLocalWalletFromMnemonic(args);
} catch (err) {
if (err instanceof Error && err.message === 'Recovery phrase is required.') {
focusMnemonicField('Enter your recovery phrase to continue.');
return;
}
throw err;
} Prevention
- Disable submit until word count is 12 or 24.
- Trim and collapse whitespace on paste before counting words.
- Never call wallet setup with programmatic imports that have not been length-checked.
When it happens
Trigger: Calling the setup flow with an empty string, a whitespace-only string, or a value whose split/filter(Boolean) yields []. Typical UI cause: the submit handler firing before the textarea state binds, or the continue button enabled with an empty field.
Common situations: Form state desync (controlled textarea not wired), paste handler stripping content, autocomplete/password managers clearing the field, or an import flow handing an empty mnemonic through.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Failed to secure recovery phrase. Please try again.
- Invalid : . Must be a positive integer.
- Invalid : . Must be a positive integer.
- " " is required
- agent ` ` is a `worker` tier and must not list ` ` in its…
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/3b7a400a4c5233d3.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/features/wallet/setupLocalWalletFromMnemonic.ts:22
deriveWalletAccountsFromMnemonic,
type WalletSetupSource,
} from '../../utils/cryptoKeys';
import { openhumanEncryptSecret } from '../../utils/tauriCommands/auth';
export async function persistLocalWalletFromMnemonic(args: {
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)