ruvnet/ruflo · error

Value exceeds maximum size of

Error message

Value exceeds maximum size of ${MAX_VALUE_SIZE} bytes

What it means

memory_store rejects values larger than MAX_VALUE_SIZE: 1 MiB (1,048,576) measured as value.length on the string. validateMemoryInput throws before anything is persisted, protecting the hybrid memory backend (SQLite rows plus HNSW vector index) from being bloated by a single entry. There is no environment override — the ceiling is fixed in code.

Solutions

  1. Chunk the payload into multiple entries under a common key prefix (doc-1 ... doc-N) and reassemble on read
  2. Store a reference instead of the content: write the blob to disk or object storage, then memory_store its path/URL plus metadata
  3. Compress then encode (zlib deflate + base64) if the content is compressible — verify the result is still under 1 MiB
  4. Check value.length at the call site before invoking memory_store and fail fast with your own message

Example fix

// before
await mcp.callTool('memory_store', {
  key: 'page-cache',
  value: html, // 2.4MB scraped page -> Value exceeds maximum size of 1048576 bytes
});

// after
for (let i = 0; i < html.length; i += 512 * 1024) {
  await mcp.callTool('memory_store', { key: `page-cache:${i / (512 * 1024)}`, value: html.slice(i, i + 512 * 1024) });
}
Defensive patterns

Strategy: validation

Validate before calling

const MAX_VALUE_SIZE = 1024 * 1024;
function chunkedValues(value: string, chunkSize = 512 * 1024): Array<{ key: string; value: string }> {
  if (value.length <= MAX_VALUE_SIZE) return [{ key: '0', value }];
  const chunks: Array<{ key: string; value: string }> = [];
  for (let i = 0; i < value.length; i += chunkSize) chunks.push({ key: String(i / chunkSize), value: value.slice(i, i + chunkSize) });
  return chunks;
}
// for (const c of chunkedValues(blob)) await memoryStore({ key: `${baseKey}:${c.key}`, value: c.value });

Try / catch

try {
  await memoryStore({ key, value });
} catch (e) {
  if (e instanceof Error && e.message.includes('Value exceeds maximum size')) {
    // split or externalize the payload, then retry — retrying identical input always fails
  }
  throw e;
}

Prevention

When it happens

Trigger: memory_store whose value is a full JSON dump, base64 blob, log file, or concatenated report whose string length exceeds 1,048,576 characters; caching an entire HTTP response body or an LLM transcript in a single entry.

Common situations: Caching API responses or scraped pages into memory; pasting base64-encoded assets; append-style pipelines whose value grows until it crosses 1 MiB; migrating from a KV store that had no size limit.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@9c61c86f06 (2026-08-18). Data as JSON: /api/errors/e26ea06d29cce2d5. Report an issue: GitHub.

Appendix: source

Thrown at v3/@claude-flow/cli/src/mcp-tools/memory-tools.ts:76

}

// D-2: Input bounds for memory parameters
const MAX_KEY_LENGTH = 1024;
const MAX_VALUE_SIZE = 1024 * 1024; // 1MB
const MAX_QUERY_LENGTH = 4096;

// #1425 — single source of truth for the dangerous-character set rejected by
// validateMemoryInput. Imported by sanitizeMemoryKey so write-side sanitization
// and read-side rejection can never drift apart (the symmetry bug behind #1884).
const DANGEROUS_KEY_CHARS = /[;&|`$(){}[\]<>!#\\\0]|\.\.[/\\]/g;
const DANGEROUS_KEY_PATTERN = /[;&|`$(){}[\]<>!#\\\0]|\.\.[/\\]/;

function validateMemoryInput(key?: string, value?: string, query?: string, namespace?: string): void {
  if (key && key.length > MAX_KEY_LENGTH) {
    throw new Error(`Key exceeds maximum length of ${MAX_KEY_LENGTH} characters`);
  }
  if (value && value.length > MAX_VALUE_SIZE) {
    throw new Error(`Value exceeds maximum size of ${MAX_VALUE_SIZE} bytes`);
  }
  if (query && query.length > MAX_QUERY_LENGTH) {
    throw new Error(`Query exceeds maximum length of ${MAX_QUERY_LENGTH} characters`);
  }
  // Reject path traversal and shell metacharacters in keys/namespaces (#1425)
  if (key && DANGEROUS_KEY_PATTERN.test(key)) {
    throw new Error('Key contains disallowed characters');
  }
  if (namespace && DANGEROUS_KEY_PATTERN.test(namespace)) {
    throw new Error('Namespace contains disallowed characters');
  }
}

// #1884 — sanitize a key produced from arbitrary input (markdown headings,
// frontmatter names, file names) so it survives validateMemoryInput on the
// read/delete path. Replaces every dangerous char with `_`. Truncates to
// MAX_KEY_LENGTH so the bound check in validateMemoryInput also passes.
// Keep this in sync with DANGEROUS_KEY_PATTERN — they share DANGEROUS_KEY_CHARS.

View on GitHub (pinned to 9c61c86f06)