ComposioHQ/composio · error · KeyringError
BadEncoding
BadEncoding
Error message
BadEncoding
What it means
Entry.getPassword() failed to UTF-8 decode the stored secret bytes. The credential was stored as opaque binary (via setSecret) and is not valid UTF-8 text, so decoding it as a password string raises KeyringError kind 'BadEncoding'.
Source
Thrown at ts/packages/cli-keyring/src/core/entry.ts:84
* Store `password` as UTF-8 bytes under this entry's specifier.
* Overwrites any existing value.
*/
async setPassword(password: string): Promise<void> {
await this.setSecret(textEncoder.encode(password));
}
/**
* Fetch the stored value and decode it as UTF-8. Throws
* `KeyringError({ kind: 'NoEntry' })` if nothing was stored, or
* `KeyringError({ kind: 'BadEncoding', bytes })` if the stored bytes
* aren't valid UTF-8 — matching keyring-rs's `Error::BadEncoding`.
*/
async getPassword(): Promise<string> {
const bytes = await this.getSecret();
try {
return textDecoder.decode(bytes);
} catch {
throw new KeyringError({ kind: 'BadEncoding', bytes });
}
}
/** Store raw bytes. */
async setSecret(secret: Uint8Array): Promise<void> {
await this.resolveStore().setSecret(this.service, this.user, secret, this.modifiers);
}
/** Fetch raw bytes. Throws `NoEntry` if nothing matches. */
async getSecret(): Promise<Uint8Array> {
return this.resolveStore().getSecret(this.service, this.user, this.modifiers);
}
/** Delete the credential. Throws `NoEntry` if it didn't exist. */
async deleteCredential(): Promise<void> {
await this.resolveStore().deleteCredential(this.service, this.user, this.modifiers);
}
View on GitHub (pinned to 64b1b85502)
Solutions
- Use getSecret() to read raw bytes instead of getPassword() when the value is binary
- Store text via setPassword() if a string is expected later
- Delete and re-store the entry if it is corrupted
Example fix
// before const pw = await entry.getPassword(); // after const bytes = await entry.getSecret(); // handle as binary
Defensive patterns
Strategy: type-guard
Validate before calling
// Prefer bytes API when value may be binary const bytes = await entry.getSecret();
Try / catch
catch (e) { if (e instanceof KeyringError && e.kind === 'BadEncoding') { return await entry.getSecret(); } throw e; } Prevention
- Use setSecret/getSecret for binary credentials
- Use setPassword only for true text values
When it happens
Trigger: Calling getPassword() on an entry whose secret was written with setSecret(binaryUint8) containing non-UTF-8 bytes.
Common situations: Mixing binary secret storage (tokens, keys) with the string-oriented getPassword API; corrupted keychain entries.
Related errors
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/9c34c6a9a9d9a2eb.
Report an issue: GitHub.