Summary
@opik/opik-openclaw treats OpenClaw media://inbound/... URIs as local absolute paths. The media extractor captures //inbound/example.jpg, normalizes it to /inbound/example.jpg, and the attachment uploader then fails with ENOENT.
In OpenClaw deployments, the actual inbound file is stored under the OpenClaw state directory, for example $OPENCLAW_STATE_DIR/media/inbound/example.jpg.
Steps to reproduce
- Run OpenClaw with
@opik/opik-openclaw attachment upload enabled.
- Send a Telegram/image turn that includes an OpenClaw media reference such as
media://inbound/example.jpg.
- Let Opik process the
llm_input payload.
- Observe the attachment upload warning.
Minimal parser reproduction against @opik/opik-openclaw@0.2.17:
import { collectMediaPathsFromString } from "@opik/opik-openclaw/dist/src/service/media.js";
const paths = new Set();
collectMediaPathsFromString("media://inbound/example.jpg", paths);
console.log([...paths]);
Actual output:
[ "/inbound/example.jpg" ]
Expected behavior
The plugin should not convert media://inbound/... to /inbound/....
Reasonable behavior would be either:
- ignore unresolved
media:// URIs; or
- resolve OpenClaw-managed inbound media through
$OPENCLAW_STATE_DIR/media/inbound/... before upload.
Actual behavior
The plugin attempts to stat /inbound/..., which usually does not exist, while the actual file exists under $OPENCLAW_STATE_DIR/media/inbound/....
Environment
- OpenClaw version:
2026.5.26
@opik/opik-openclaw versions reproduced: 0.2.15, 0.2.17
- Node version:
22.21.1
- Deployment: Linux container gateway
- Channel: Telegram image turn
Relevant logs
opik: attachment upload failed (llm_input sessionKey=<redacted>, entity=trace:<redacted>, path=/inbound/ae3fd1cd-d6d8-4887-bc46-8f9940aaa576.jpg): Error: ENOENT: no such file or directory, stat '/inbound/ae3fd1cd-d6d8-4887-bc46-8f9940aaa576.jpg'
at async stat (node:internal/fs/promises:1039:18)
at async uploadFileAttachment (.../attachment-uploader.js:42:21)
Summary
@opik/opik-openclawtreats OpenClawmedia://inbound/...URIs as local absolute paths. The media extractor captures//inbound/example.jpg, normalizes it to/inbound/example.jpg, and the attachment uploader then fails withENOENT.In OpenClaw deployments, the actual inbound file is stored under the OpenClaw state directory, for example
$OPENCLAW_STATE_DIR/media/inbound/example.jpg.Steps to reproduce
@opik/opik-openclawattachment upload enabled.media://inbound/example.jpg.llm_inputpayload.Minimal parser reproduction against
@opik/opik-openclaw@0.2.17:Actual output:
Expected behavior
The plugin should not convert
media://inbound/...to/inbound/....Reasonable behavior would be either:
media://URIs; or$OPENCLAW_STATE_DIR/media/inbound/...before upload.Actual behavior
The plugin attempts to
stat/inbound/..., which usually does not exist, while the actual file exists under$OPENCLAW_STATE_DIR/media/inbound/....Environment
2026.5.26@opik/opik-openclawversions reproduced:0.2.15,0.2.1722.21.1Relevant logs