Skip to content

fix(deepagents): base64-encode binary FileData content in StoreBackend store values - #642

Open
Nitsan Cohen (NitsanCohen770) wants to merge 1 commit into
langchain-ai:mainfrom
NitsanCohen770:fix/store-backend-json-safe-binary
Open

fix(deepagents): base64-encode binary FileData content in StoreBackend store values#642
Nitsan Cohen (NitsanCohen770) wants to merge 1 commit into
langchain-ai:mainfrom
NitsanCohen770:fix/store-backend-json-safe-binary

Conversation

@NitsanCohen770

Copy link
Copy Markdown

Problem

StoreBackend.convertFileDataToStoreValue passes binary FileData.content to store.put() as a raw Uint8Array. BaseStore implementations that persist values as JSON — e.g. the LangGraph Postgres store, whose value column is JSONB — round-trip every value through JSON serialization, which turns a Uint8Array into a numeric-keyed byte map:

{"content": {"0": 137, "1": 80, "2": 78, ...}}

On the way back, convertStoreItemToFileData rejects that shape (Store item does not contain valid FileData fields), so any binary file written through StoreBackend against a JSON-backed store is stored successfully and then permanently unreadable. This hits more than images: any extension without a recognized text MIME (.jsonl included) takes the binary path in uploadFiles.

Fix

convertFileDataToStoreValue base64-encodes binary content and marks the store value with encoding: "base64"; convertStoreItemToFileData reverses it. Text content keeps its plain-string representation (no store-format change), and values written by in-memory stores as real Uint8Arrays still pass through untouched.

One existing assertion updated: read() of a binary file now returns a defensive copy rather than an alias of store-internal state, so the offset/limit identity check (toBe) becomes a value check (toStrictEqual) — object identity across reads was an artifact of the in-memory store returning its internal buffer by reference, not a documented contract.

Test

Adds a regression test that wraps InMemoryStore with JSON round-tripping on put (the exact behavior of a JSONB-backed store) and asserts a PNG byte payload survives uploadFiles → readRaw/downloadFiles byte-for-byte, while text files keep a plain-string store representation with no encoding marker.

Verification

Hit in production against the LangGraph PostgresStore: every .jsonl file uploaded through StoreBackend was written as an unreadable byte map (verified by inspecting the JSONB rows) and failed FileData validation on read. With this change the same flow round-trips correctly. libs/deepagents vitest suite: 1178 passing locally (the 6 pre-existing *.int.test.ts typecheck errors about @langchain/sandbox-standard-tests are unrelated and present on main).

…d store values

BaseStore implementations that persist values as JSON (e.g. the Postgres
store's JSONB column) cannot represent a raw Uint8Array: JSON
serialization turns it into a numeric-keyed byte map ({"0":123,...})
that fails FileData validation on read, so any binary file written
through StoreBackend against such a store was stored unreadable.

convertFileDataToStoreValue now base64-encodes binary content with an
encoding: "base64" marker and convertStoreItemToFileData reverses it.
Text content keeps its plain-string representation, and in-memory
stores are unaffected (reads now return a defensive copy rather than an
alias of store-internal state, so the offset/limit identity assertion
becomes a value assertion).
@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

Nitsan Cohen (@NitsanCohen770) is attempting to deploy a commit to the LangChain Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 68cfc25

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

deepagents-acp

npm i https://pkg.pr.new/deepagents-acp@642

deepagents

npm i https://pkg.pr.new/deepagents@642

@langchain/sandbox-standard-tests

npm i https://pkg.pr.new/@langchain/sandbox-standard-tests@642

@langchain/daytona

npm i https://pkg.pr.new/@langchain/daytona@642

@langchain/deno

npm i https://pkg.pr.new/@langchain/deno@642

@langchain/modal

npm i https://pkg.pr.new/@langchain/modal@642

@langchain/node-vfs

npm i https://pkg.pr.new/@langchain/node-vfs@642

@langchain/quickjs

npm i https://pkg.pr.new/@langchain/quickjs@642

commit: 68cfc25

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant