bytedance/deer-flow · warning · HTTPException
Binary artifacts cannot be edited
Error message
Binary artifacts cannot be edited
What it means
HTTP 415 from _load_editable_artifact: the artifact's bytes contain a NUL byte (b'\x00'), the heuristic for binary content. The panel editor is text-only; round-tripping binary through a JSON string field would corrupt it, so such artifacts are refused for editing.
Source
Thrown at backend/app/gateway/routers/artifacts.py:93
def _load_editable_artifact(actual_path: Path, path: str, expected_sha256: str) -> tuple[bytes, os.stat_result]:
try:
file_stat = os.lstat(actual_path)
except FileNotFoundError:
raise HTTPException(status_code=404, detail=f"Artifact not found: {path}") from None
if stat.S_ISLNK(file_stat.st_mode):
raise HTTPException(status_code=415, detail="Symlinked artifacts cannot be edited")
if not stat.S_ISREG(file_stat.st_mode):
raise HTTPException(status_code=400, detail=f"Path is not a file: {path}")
if file_stat.st_size > MAX_EDITABLE_ARTIFACT_BYTES:
raise HTTPException(status_code=413, detail="Artifact is too large to edit")
current = actual_path.read_bytes()
if len(current) > MAX_EDITABLE_ARTIFACT_BYTES:
raise HTTPException(status_code=413, detail="Artifact is too large to edit")
if b"\x00" in current:
raise HTTPException(status_code=415, detail="Binary artifacts cannot be edited")
try:
current.decode("utf-8")
except UnicodeDecodeError:
raise HTTPException(status_code=415, detail="Only UTF-8 text artifacts can be edited") from None
current_sha256 = hashlib.sha256(current).hexdigest()
if current_sha256 != expected_sha256:
raise HTTPException(status_code=412, detail="Artifact changed since it was opened")
return current, file_stat
def _encode_artifact_update(content: str) -> bytes:
encoded = content.encode("utf-8")
if len(encoded) > MAX_EDITABLE_ARTIFACT_BYTES:
raise HTTPException(status_code=413, detail="Artifact is too large to edit")
if b"\x00" in encoded:
raise HTTPException(status_code=415, detail="Binary content cannot be saved as an artifact")
return encodedView on GitHub (pinned to 1dd6ba1acb)
Solutions
- Use the preview/download path (GET artifact) instead of the edit path for binary files
- Convert the artifact to UTF-8 text before offering edit (e.g. export CSV instead of XLSX)
- If UTF-16 was intended, re-encode as UTF-8 — UTF-16 files always contain NULs and are rejected by design
Defensive patterns
Strategy: validation
Validate before calling
def looks_editable_text(data: bytes) -> bool:
return b"\x00" not in data Type guard
def is_editable_text_bytes(data: bytes) -> bool:
"""Mirrors the Gateway's binary heuristic."""
if b"\x00" in data:
return False
try:
data.decode("utf-8")
return True
except UnicodeDecodeError:
return False Try / catch
if resp.status_code == 415 and "Binary" in resp.text:
show_binary_preview_or_download(path) Prevention
- Sniff NUL bytes client-side before enabling Edit on fetched previews
- Prefer UTF-8 everywhere; UTF-16/32 outputs will always be refused
- Have the agent emit human-editable artifacts as UTF-8 text and keep binaries separate
When it happens
Trigger: PUT edit-artifact (open/save) on any outputs file containing NUL bytes: images, serialized objects, databases, some PDFs/office formats even when MIME-sniffed as text.
Common situations: Users clicking Edit on generated binaries whose extension suggested text, agents writing pickle/parquet/sqlite outputs, UTF-16 files (NUL-heavy) produced on other platforms.
Related errors
- Only UTF-8 text artifacts can be edited
- Binary content cannot be saved as an artifact
- Skill archives cannot be edited in the artifacts panel
- Symlinked artifacts cannot be edited
- Only files in /mnt/user-data/outputs can be edited
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/bcd275cc4c6a3783.
Report an issue: GitHub.