{"record":{"id":"bcd275cc4c6a3783","repo":"bytedance/deer-flow","slug":"binary-artifacts-cannot-be-edited","errorCode":null,"errorMessage":"Binary artifacts cannot be edited","messagePattern":"Binary artifacts cannot be edited","errorType":"http","errorClass":"HTTPException","httpStatus":415,"severity":"warning","filePath":"backend/app/gateway/routers/artifacts.py","lineNumber":93,"sourceCode":"\n\ndef _load_editable_artifact(actual_path: Path, path: str, expected_sha256: str) -> tuple[bytes, os.stat_result]:\n    try:\n        file_stat = os.lstat(actual_path)\n    except FileNotFoundError:\n        raise HTTPException(status_code=404, detail=f\"Artifact not found: {path}\") from None\n    if stat.S_ISLNK(file_stat.st_mode):\n        raise HTTPException(status_code=415, detail=\"Symlinked artifacts cannot be edited\")\n    if not stat.S_ISREG(file_stat.st_mode):\n        raise HTTPException(status_code=400, detail=f\"Path is not a file: {path}\")\n    if file_stat.st_size > MAX_EDITABLE_ARTIFACT_BYTES:\n        raise HTTPException(status_code=413, detail=\"Artifact is too large to edit\")\n\n    current = actual_path.read_bytes()\n    if len(current) > MAX_EDITABLE_ARTIFACT_BYTES:\n        raise HTTPException(status_code=413, detail=\"Artifact is too large to edit\")\n    if b\"\\x00\" in current:\n        raise HTTPException(status_code=415, detail=\"Binary artifacts cannot be edited\")\n    try:\n        current.decode(\"utf-8\")\n    except UnicodeDecodeError:\n        raise HTTPException(status_code=415, detail=\"Only UTF-8 text artifacts can be edited\") from None\n\n    current_sha256 = hashlib.sha256(current).hexdigest()\n    if current_sha256 != expected_sha256:\n        raise HTTPException(status_code=412, detail=\"Artifact changed since it was opened\")\n    return current, file_stat\n\n\ndef _encode_artifact_update(content: str) -> bytes:\n    encoded = content.encode(\"utf-8\")\n    if len(encoded) > MAX_EDITABLE_ARTIFACT_BYTES:\n        raise HTTPException(status_code=413, detail=\"Artifact is too large to edit\")\n    if b\"\\x00\" in encoded:\n        raise HTTPException(status_code=415, detail=\"Binary content cannot be saved as an artifact\")\n    return encoded","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/app/gateway/routers/artifacts.py#L75-L111","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def looks_editable_text(data: bytes) -> bool:\n    return b\"\\x00\" not in data","typeGuard":"def is_editable_text_bytes(data: bytes) -> bool:\n    \"\"\"Mirrors the Gateway's binary heuristic.\"\"\"\n    if b\"\\x00\" in data:\n        return False\n    try:\n        data.decode(\"utf-8\")\n        return True\n    except UnicodeDecodeError:\n        return False","tryCatchPattern":"if resp.status_code == 415 and \"Binary\" in resp.text:\n    show_binary_preview_or_download(path)","preventionTips":["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"],"tags":["api","artifacts","binary","http-415","encoding"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}