stablyai/orca · error · Error
Terminal history seed transfer exceeds retained byte limit
Error message
Terminal history seed transfer exceeds retained byte limit
What it means
Thrown by TerminalHistorySeedTransferRegistry.append when appending a chunk would push cumulative retained bytes over maxRetainedBytes (default 200 MB, TERMINAL_HISTORY_CHECKPOINT_MAX_BYTES) or would exceed the manifest's declared total codeUnits. The registry tracks retainedBytes across all transfers to bound daemon memory; a single append that breaches either budget is rejected and the transfer is left consistent.
Source
Thrown at src/main/daemon/terminal-history-seed-transfer-registry.ts:67
}
append(ownerId: string, transferId: string, index: number, data: string): void {
const transfer = this.getOwned(ownerId, transferId)
if (transfer.finished) {
throw new Error('Terminal history seed transfer is already finished')
}
if (index !== transfer.chunks.length || index >= transfer.manifest.chunkCount) {
throw new Error('Terminal history seed chunk sequence mismatch')
}
if (data.length === 0 || data.length > TERMINAL_HISTORY_SEED_CHUNK_CODE_UNITS) {
throw new Error('Terminal history seed chunk size is invalid')
}
const utf8Bytes = Buffer.byteLength(data, 'utf8')
if (
transfer.codeUnits + data.length > transfer.manifest.codeUnits ||
this.retainedBytes + utf8Bytes > this.maxRetainedBytes
) {
throw new Error('Terminal history seed transfer exceeds retained byte limit')
}
transfer.chunks.push(data)
transfer.codeUnits += data.length
transfer.utf8Bytes += utf8Bytes
transfer.hash.update(Buffer.from(data, 'utf16le'))
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
) {View on GitHub (pinned to 1136503c6a)
Solutions
- Re-measure the seed with measureTerminalHistorySeed and send a manifest whose codeUnits matches the actual chunks exactly.
- Reduce the number of concurrent transfers so retained bytes stay under 200 MB.
- Chunk the seed with iterateTerminalHistorySeedChunks so chunk sizes and totals match the manifest.
- Abort and restart the transfer with a corrected manifest if the size estimate was wrong.
Example fix
// before: manifest with a guessed codeUnits
registry.start(id, { chunkCount, codeUnits: guessed, sha256 })
// after: measure exact metrics
const { chunkCount, codeUnits, sha256 } = measureTerminalHistorySeed(segments)
registry.start(id, { chunkCount, codeUnits, sha256 }) Defensive patterns
Strategy: validation
Validate before calling
import { measureTerminalHistorySeed, iterateTerminalHistorySeedChunks } from './terminal-history-seed-chunks'
// Build the manifest from the exact chunks you will send
const metrics = measureTerminalHistorySeed(segments)
// Then verify each append stays within manifest.codeUnits and global budget
function appendFits(transferCodeUnits: number, chunk: string, manifestCodeUnits: number): boolean {
return transferCodeUnits + chunk.length <= manifestCodeUnits
} Type guard
function isSeedRetainedByteLimit(e: unknown): boolean {
return e instanceof Error && e.message === 'Terminal history seed transfer exceeds retained byte limit'
} Try / catch
try {
registry.append(ownerId, transferId, index, data)
} catch (e) {
if (e instanceof Error && e.message === 'Terminal history seed transfer exceeds retained byte limit') {
// abort and restart with a corrected manifest / fewer concurrent transfers
registry.abort(ownerId, transferId)
} else { throw e }
} Prevention
- Always measure with measureTerminalHistorySeed so manifest.codeUnits matches the chunks exactly.
- Chunk with iterateTerminalHistorySeedChunks to keep boundaries consistent.
- Limit concurrent transfers so total retained bytes stay under 200 MB.
When it happens
Trigger: append(ownerId, transferId, index, data) where this.retainedBytes + utf8Bytes(data) > maxRetainedBytes, or transfer.codeUnits + data.length > manifest.codeUnits. The manifest declared fewer code units than the client is sending, or total memory is saturated.
Common situations: A manifest whose codeUnits understates the actual seed size; many concurrent transfers whose retained bytes collectively exceed 200 MB; a client re-chunking with different boundaries than the manifest measured.
Related errors
- Too many pending terminal history seed transfers
- Terminal history seed transfer digest mismatch
- Electron did not expose GC; keep --js-flags=--expose-gc in t
- Could not read physical footprint for PIDs ${pids.join(', ')
- ${tag} does not contain ${name}
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/4f834b72e757824b.
Report an issue: GitHub.