Skip to content

fix(image): load Photon via runtime eval on compiled binaries; surface typed errors in omitted-image message#69

Merged
Alezander9 merged 1 commit into
mainfrom
fix/photon-load-and-typed-omitted-message
May 15, 2026
Merged

fix(image): load Photon via runtime eval on compiled binaries; surface typed errors in omitted-image message#69
Alezander9 merged 1 commit into
mainfrom
fix/photon-load-and-typed-omitted-message

Conversation

@Alezander9
Copy link
Copy Markdown
Member

@Alezander9 Alezander9 commented May 15, 2026

Closes #68.

Symptom

On the Windows v0.1.5 release binary, every browser_execute screenshot and every read of an image file returns

[1 image omitted: could not be resized below the inline image size limit.]

even for sub-200-byte PNGs that cannot physically exceed the 4.5 MB ceiling. The misleading message hid a real Photon load failure and burned hours of user + agent debugging.

Root cause (two stacked bugs)

  1. Real: Photon WASM fails to load in the Bun compiled binary on Windows. The patched photon_rs.js falls back to require("path").join(__dirname, "photon_rs_bg.wasm") when globalThis.__OPENCODE_PHOTON_WASM_PATH is unset at the right moment, and Bun's static bundling evaluates that require before the global is observable, so the wasm path never resolves under B:/~BUN/root/. image.normalize() then fails with PhotonUnavailableError.
  2. Hiding the real bug: the loader's catch { return null } swallowed the import error silently, and session/processor.ts hard-coded the omitted-image message to the size-failure wording regardless of which Image.Error tag fired.

Fix

packages/opencode/src/image/image.ts

  • Log the swallowed Photon import error via log.warn("photon image processor unavailable", { error, stack }).
  • When with: { type: "file" } yields an asset path (compiled binary), evaluate photon_rs.js via new Function(...) over await Bun.file(photonJs).text() after setting __OPENCODE_PHOTON_WASM_PATH. The patched module then reads from the embedded wasm asset. Falls back to plain await import("@silvia-odwyer/photon-node") in dev/test where the import returns the module record directly.

packages/opencode/src/session/processor.ts

  • Extract the typed error per failure via Cause.findErrorOption and switch on _tag:
    • ImagePhotonUnavailableError -> "image processor unavailable in this runtime"
    • ImageInvalidDataUrlError -> "attachment URL malformed"
    • ImageDecodeError -> "could not decode image data"
    • ImageSizeError -> keep the original "could not be resized below the inline image size limit"
  • Group failures by reason so a single tool call dropping multiple images for different reasons emits one line per distinct reason.

Verification

  • bun typecheck from packages/opencode/: clean.
  • bun test test/image/image.test.ts: 3 pass, 0 fail (existing tests unchanged).
  • End-to-end on a freshly built Windows bcode.exe:
    • 192-byte real PNG (Read tool): image attaches, no omitted line.
    • 67-byte malformed PNG: [1 image omitted: could not decode image data.] (accurate DecodeError, not misleading size).
  • Confirmed against the installed bcode 0.1.5 binary reproducing the original symptom before the fix.

Summary by cubic

Fixes Photon loading in Windows compiled binaries and shows accurate reasons when images are omitted. Screenshots and file reads now work on the Windows build instead of always being dropped.

  • Bug Fixes
    • Load @silvia-odwyer/photon-node in compiled binaries by evaluating the embedded photon_rs.js via new Function(...) after setting __OPENCODE_PHOTON_WASM_PATH. Falls back to dynamic import in dev/test.
    • Log Photon load failures with log.warn instead of swallowing the error.
    • Show reason-specific omitted-image messages (processor unavailable, malformed URL, decode error, or size limit). Group multiple failures by reason to keep output concise.

Written for commit 698f524. Summary will update on new commits. Review in cubic

…e typed errors in omitted-image message

The Bun compiled binary on Windows could not resolve photon_rs_bg.wasm
from the patched photon_rs.js fallback path under the bunfs `__dirname`,
so `image.normalize()` always failed with PhotonUnavailableError. Two
upstream bugs stacked to hide this from users:

1. The Photon import error was swallowed silently in the catch block.
2. The session processor hard-coded the omitted-image message to the
   size-failure wording regardless of which Image.Error tag fired.

Result: every screenshot and image-file read on the v0.1.5 Windows
binary returned `[1 image omitted: could not be resized below the
inline image size limit.]` — even for sub-200 byte PNGs — and the
underlying load failure left no trace in logs.

This commit:
- Logs the swallowed Photon import error via log.warn so future
  regressions surface in debug logs.
- Evaluates the patched photon_rs.js via `new Function(...)` over
  `await Bun.file(photonJs).text()` when `with: { type: 'file' }`
  yields an asset path (compiled binary), after setting the
  `__OPENCODE_PHOTON_WASM_PATH` global so the patched module reads
  from the embedded wasm asset. Falls back to plain dynamic import in
  dev/test where the import returns the module record directly.
- Switches the omitted-image system message in
  `session/processor.ts` on the typed error tag extracted from the
  Effect Cause via `Cause.findErrorOption`:
    PhotonUnavailableError -> image processor unavailable in this runtime
    InvalidDataUrlError    -> attachment URL malformed
    DecodeError            -> could not decode image data
    SizeError              -> could not be resized below the inline image size limit
  Groups multiple failures by reason so a single tool call emitting
  several dropped images still reports one line per distinct reason.

Closes #68
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Re-trigger cubic

@Alezander9 Alezander9 merged commit b6a4c98 into main May 15, 2026
3 checks passed
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.

Screenshot attachments silently dropped with misleading "could not be resized" message

1 participant