paperclipai/paperclip · error
Chat SDK ${kind} state exceeds the ${this.maxValueBytes}-byt
Error message
Chat SDK ${kind} state exceeds the ${this.maxValueBytes}-byte limit What it means
After serializing the state envelope, the adapter enforces a per-value byte budget (this.maxValueBytes). Values whose serialized JSON exceeds the limit are rejected to keep persistence records bounded. The message includes the kind and the configured byte limit.
Source
Thrown at server/src/services/chat-sdk-state.ts:506
return new Date(this.now().getTime() + ttlMs);
}
private envelope(kind: StateKind, value: unknown): StateEnvelope {
const envelope: StateEnvelope = {
kind,
schemaVersion: STATE_SCHEMA_VERSION,
value,
};
let serialized: string;
try {
serialized = JSON.stringify(envelope);
} catch (error) {
throw new Error(`Chat SDK ${kind} state is not JSON-serializable`, {
cause: error,
});
}
if (Buffer.byteLength(serialized) > this.maxValueBytes) {
throw new Error(
`Chat SDK ${kind} state exceeds the ${this.maxValueBytes}-byte limit`,
);
}
return envelope;
}
private async compareAndSet(
key: string,
expectedVersion: number | null,
kind: StateKind,
value: unknown,
expiresAt: Date | null,
): Promise<boolean> {
return this.persistence.compareAndSet({
...this.scope,
key,
expectedVersion,
expiresAt,View on GitHub (pinned to 01ad858492)
Solutions
- Reduce payload size before storing: truncate, summarize, or store an external reference/pointer instead of the full data
- Move large blobs to object storage and keep only a key in state
- Raise maxValueBytes if the limit is genuinely too small (and verify backend record limits)
Example fix
// before
await state.set(kind, key, { transcript: allMessages }); // too large
// after
const recent = allMessages.slice(-50);
await state.set(kind, key, { transcript: recent, truncated: allMessages.length - recent.length }); Defensive patterns
Strategy: validation
Validate before calling
if (Buffer.byteLength(JSON.stringify(envelope)) > maxValueBytes) throw new Error('state too large before set'); Try / catch
try { await state.set(kind, key, value); } catch (err) { if (/exceeds the .*-byte limit/.test((err as Error).message)) { value = truncate(value); return state.set(kind, key, value); } throw err; } Prevention
- Bound transcript/list growth before writing
- Store large blobs externally, keep references in state
- Pre-check serialized size for payloads near the limit
When it happens
Trigger: Storing very large payloads: long conversation transcripts, big arrays, embedded base64 blobs, or accumulated list/queue data whose JSON exceeds maxValueBytes.
Common situations: A transcript growing unbounded over a long session; embedding file contents or screenshots as base64 in state; a lowered maxValueBytes config after upgrading; many small writes that compound into one large record.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
- dropping 1 event with a non-serializable dimension (circular
- ACPX snapshot exceeds its byte bound
- Image exceeds attachment bound
- Chat SDK ${kind} state is not JSON-serializable
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/d49f24b4560e3590.
Report an issue: GitHub.