bytedance/deer-flow · warning · HTTPException
Only UTF-8 text artifacts can be edited
Error message
Only UTF-8 text artifacts can be edited
What it means
HTTP 415 from _load_editable_artifact: current.decode('utf-8') raised UnicodeDecodeError — the file has no NUL bytes (so it passed the binary heuristic) but is not valid UTF-8, e.g. Latin-1/Shift-JIS/CP1252 text. Editing requires an exact byte-preserving round trip, which non-UTF-8 encodings cannot guarantee through the string-based API.
Source
Thrown at backend/app/gateway/routers/artifacts.py:97
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 encoded
def _replace_artifact_atomically(actual_path: Path, content: bytes, file_stat: os.stat_result) -> None:
temp_fd, temp_path_str = tempfile.mkstemp(prefix=_ARTIFACT_EDIT_TEMP_PREFIX, dir=actual_path.parent)View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Re-encode the file to UTF-8 in the sandbox (iconv) and reopen the editor
- Generate artifacts as UTF-8 at the source (configure the producing tool's locale/encoding)
- Keep non-UTF-8 artifacts read-only: preview or download instead of edit
Example fix
# before: file is latin-1; edit PUT returns 415 # after: re-encode in sandbox, then edit iconv -f latin-1 -t utf-8 outputs/report.txt > outputs/report.utf8.txt && mv outputs/report.utf8.txt outputs/report.txt
Defensive patterns
Strategy: validation
Validate before calling
def is_valid_utf8(data: bytes) -> bool:
try:
data.decode("utf-8")
return True
except UnicodeDecodeError:
return False Try / catch
if resp.status_code == 415 and "UTF-8" in resp.text:
prompt_reencode_to_utf8(path) # e.g. sandbox: iconv -f latin-1 -t utf-8 Prevention
- Standardize on UTF-8 for all generated artifacts
- Client-side: attempt TextDecoder('utf-8', {fatal:true}) on preview bytes to pre-flag files
- Never 'repair' encoding by editing bytes directly — re-encode via tooling
When it happens
Trigger: PUT edit-artifact on a text file written in a legacy encoding (ISO-8859-1 logs, CP1252 reports, Shift-JIS dumps) inside outputs.
Common situations: Agents copying OS-generated logs from Windows hosts, artifacts derived from legacy datasets, or mixed-encoding concatenations that happen to lack NULs.
Related errors
- Binary artifacts cannot be edited
- Skill archives cannot be edited in the artifacts panel
- Symlinked artifacts cannot be edited
- Binary content cannot be saved as an artifact
- 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/b7c20a0c84977dd0.
Report an issue: GitHub.