Skip to content

SQLITE_TOOBIG persisting large text/tool-output session entries (follow-up to #240, which only chunked images) #289

Description

@kalepail

Describe the bug

Follow-up to #240 (closed/completed). The fix for #240 split sessions into per-entry rows and chunks image content across flue_image_chunks (256 KB/chunk), which keeps image data under Cloudflare Durable Object SQLite's ~2 MB per-cell string/blob limit. But the same overflow still occurs for large non-image text entries — a single tool result or verbose model turn whose JSON data cell exceeds 2 MB.

In @flue/runtime 1.0.0-beta.1, createSqlAgentExecutionStore* (the Cloudflare DO path) persists session state across three tables, but each entry's text content is stored as one un-chunked data cell:

// flue_session_entries — one row per entry, but `data` is a single JSON cell
INSERT INTO flue_session_entries (session_id, entry_id, position, data)
VALUES (?, ?, ?, ?)
ON CONFLICT (session_id, entry_id) DO UPDATE SET ...
// (data = JSON.stringify(entry) with images extracted out)

// flue_sessions — session header, also a single JSON cell
INSERT INTO flue_sessions (id, data) VALUES (?, ?)
ON CONFLICT (id) DO UPDATE SET data = excluded.data

Image blocks are extracted and chunked (flue_image_chunks, IMAGE_DATA_CHUNK_LENGTH = 256 * 1024), so images are safe. The remaining text data is stored whole. When a tool returns a large text payload (web search / full-page extraction / deep-research output) — or a model turn is very long — JSON.stringify(entry) for that single entry can exceed the 2 MB per-value limit and the save fails:

FlueError: direct(<submission-id>) failed: string or blob too big: SQLITE_TOOBIG
    at Session.throwIfError

This interrupts otherwise-valid agent runs and is non-deterministic (depends on per-run tool-output size).

Expected behavior

Persist sessions containing large text entries without exceeding the per-cell limit — i.e. give text the same treatment images already get. Options:

  • Chunk/externalize large entry data the way image blocks are chunked (a text analog of flue_image_chunks), rehydrating on load so model context is unchanged.
  • And/or compress entry data (e.g. gzip) before storing.
  • And/or spill oversized entries to R2 with a pointer, deleting on session/tree deletion.

Steps to reproduce

  1. Deploy a Cloudflare-target Flue agent using Durable Object SQLite persistence, with one or more tools that can return large text payloads (e.g. web research or full-page extraction).
  2. Ask a question that triggers a large text tool result (hundreds of KB to >2 MB) within a single entry.
  3. Observe the session save fail with string or blob too big: SQLITE_TOOBIG.

Version

@flue/runtime 1.0.0-beta.1 — Cloudflare Workers target (Durable Object SQLite backend).

Additional context

  • Hit repeatedly in a model bake-off eval harness across several models (grok, glm, kimi, nemotron); non-deterministic across runs.
  • App-side workaround we're applying: cap tool-output size (~256–512 KB/result) so no single entry approaches the limit. That avoids the crash but truncates legitimately large research output — hence this framework-side request to handle large text entries the way images are already handled.

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