stablyai/orca · error · Error

Terminal history seed transfer digest mismatch

Error message

Terminal history seed transfer digest mismatch

What it means

Thrown by TerminalHistorySeedTransferRegistry.finish when the SHA-256 of the received chunks (hashed as UTF-16LE, matching the manifest's measurement) does not equal manifest.sha256. The transfer is deleted and finish is rejected: the seed data was corrupted, truncated, reordered, or the manifest was computed differently than the chunks were sent. The mismatch is fatal because replaying corrupt scrollback would garble the terminal.

Source

Thrown at src/main/daemon/terminal-history-seed-transfer-registry.ts:91

    this.retainedBytes += utf8Bytes
    this.refreshExpiry(transferId, transfer)
  }

  finish(ownerId: string, transferId: string): void {
    const transfer = this.getOwned(ownerId, transferId)
    if (transfer.finished) {
      throw new Error('Terminal history seed transfer is already finished')
    }
    if (
      transfer.chunks.length !== transfer.manifest.chunkCount ||
      transfer.codeUnits !== transfer.manifest.codeUnits
    ) {
      throw new Error('Terminal history seed transfer is incomplete')
    }
    const digest = transfer.hash.digest('hex')
    if (digest !== transfer.manifest.sha256) {
      this.delete(transferId)
      throw new Error('Terminal history seed transfer digest mismatch')
    }
    transfer.finished = true
    this.refreshExpiry(transferId, transfer)
  }

  take(ownerId: string, transferId: string): readonly string[] {
    const transfer = this.getOwned(ownerId, transferId)
    if (!transfer.finished) {
      throw new Error('Terminal history seed transfer is not finished')
    }
    const chunks = transfer.chunks
    this.delete(transferId)
    return chunks
  }

  abort(ownerId: string, transferId: string): void {
    this.getOwned(ownerId, transferId)
    this.delete(transferId)

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Recompute the manifest with measureTerminalHistorySeed (which hashes UTF-16LE over the exact chunk boundaries) and resend.
  2. Ensure chunks are appended in index order and not mutated between measure and send.
  3. Abort the failed transfer and fall back to opening the session without a history seed.
  4. Verify the transport is not altering payload encoding (e.g., a JSON layer re-encoding strings).

Example fix

// before: manifest sha256 computed over utf8 bytes (wrong)
const sha256 = createHash('sha256').update(Buffer.from(seed, 'utf8')).digest('hex')

// after: match the registry's utf16le chunk hashing
const { sha256 } = measureTerminalHistorySeed([seed])
Defensive patterns

Strategy: fallback

Validate before calling

import { measureTerminalHistorySeed } from './terminal-history-seed-chunks'
// Compute the manifest the same way the registry hashes (utf16le per chunk)
const { sha256, codeUnits, chunkCount } = measureTerminalHistorySeed(segments)
// Re-verify locally before finish
let h = createHash('sha256')
for (const chunk of sentChunks) h.update(Buffer.from(chunk, 'utf16le'))
const ok = h.digest('hex') === sha256

Type guard

function isSeedDigestMismatch(e: unknown): boolean {
  return e instanceof Error && e.message === 'Terminal history seed transfer digest mismatch'
}

Try / catch

try {
  registry.finish(ownerId, transferId)
} catch (e) {
  if (e instanceof Error && e.message === 'Terminal history seed transfer digest mismatch') {
    // transfer is deleted; fall back to opening the session without a history seed
    await openSessionWithoutSeed(sessionId)
  } else { throw e }
}

Prevention

When it happens

Trigger: finish(ownerId, transferId) where transfer.hash.digest('hex') !== manifest.sha256. The chunkCount and codeUnits checks passed but the content digest differs.

Common situations: A chunk was corrupted in transit or reordered; the manifest's sha256 was computed over UTF-8 bytes or a different chunk boundary than the registry uses (UTF-16LE); a client re-chunked between measure and send; partial transfer where a chunk was dropped but sizes coincidentally summed correctly.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/ef355d1e2804de36. Report an issue: GitHub.