Skip to content

Bug: Silent error suppression in message unpacking hides protocol failures #626

@A-Chronicle

Description

@A-Chronicle

Problem

The sendMessageParseMessage method silently returns undefined when message unpacking fails, hiding parsing errors and making debugging cryptographic failures invisible.

Affected Code

packages/lib/sdk/src/mercury/index.ts:132-142

async sendMessageParseMessage(message: Domain.Message): Promise<Domain.Message | undefined> {
  const responseBody = await this.sendMessage<any>(message);
  try {
    const responseJSON = JSON.stringify(responseBody);
    return await this.unpackMessage(responseJSON);
  } catch {
    return undefined;  // <-- Silently swallows ALL errors
  }
}

Why This Matters

When a response message fails to decrypt/unpack (due to network corruption, wrong recipient, or cryptographic failure), the caller gets undefined with zero indication of what went wrong. The agent's message handling loop has no way to distinguish between:

  • 'no reply yet' (valid, retry later)
  • 'corrupted reply' (error, log and fail)
  • 'decryption failed' (security issue, needs investigation)

This masks critical protocol failures and makes debugging impossible.

Impact

  • Difficult error diagnosis in credential issuance/verification flows
  • Silent failures that should be logged as warnings/errors
  • No way for callers to distinguish recoverable from unrecoverable failures

Suggested Fix

Distinguish between expected and unexpected failures:

async sendMessageParseMessage(message: Domain.Message): Promise<Domain.Message | undefined> {
  const responseBody = await this.sendMessage<any>(message);
  // Only suppress if body is explicitly empty
  if (!responseBody) return undefined;
  
  try {
    const responseJSON = JSON.stringify(responseBody);
    return await this.unpackMessage(responseJSON);
  } catch (error) {
    // Log and re-throw so caller knows parsing failed
    this.logger.error('Failed to parse message response', error);
    throw new Domain.MercuryError.InvalidMessageFormatError(
      `Could not unpack message response: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions