bytedance/deer-flow · warning · HTTPException
Skill archives cannot be edited in the artifacts panel
Error message
Skill archives cannot be edited in the artifacts panel
What it means
HTTP 415 from _normalize_editable_artifact_path: paths containing '.skill/' or ending in '.skill' are refused for editing. .skill files are ZIP archives managed by the skills subsystem, not plain text artifacts, so the text editor must not rewrite them (a partial write would corrupt the archive).
Source
Thrown at backend/app/gateway/routers/artifacts.py:73
@asynccontextmanager
async def reserve_artifact_write(request: Request, thread_id: str, *, user_id: str) -> AsyncIterator[None]:
"""Serialize an artifact edit against runs and other thread mutations."""
run_manager = get_run_manager(request)
async with run_manager.reserve_thread_operation(
thread_id,
kind=ThreadOperationKind.artifact_write,
user_id=user_id,
):
yield
def _normalize_editable_artifact_path(path: str) -> str:
stripped = path.lstrip("/")
if not stripped.startswith(_EDITABLE_OUTPUTS_PREFIX):
raise HTTPException(status_code=400, detail="Only files in /mnt/user-data/outputs can be edited")
if ".skill/" in stripped or stripped.endswith(".skill"):
raise HTTPException(status_code=415, detail="Skill archives cannot be edited in the artifacts panel")
return f"/{stripped}"
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")View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Do not edit .skill archives in the artifact editor — unpack, edit, and repack via the skills API or skill tooling
- If the file is genuinely plain text that merely sits inside a '.skill' directory, move/rename it outside the .skill path first
- Use GET artifact with the skill-archive branch (it previews members read-only) to inspect contents instead of editing
Defensive patterns
Strategy: validation
Validate before calling
def is_skill_archive_path(path: str) -> bool:
stripped = path.lstrip("/")
return ".skill/" in stripped or stripped.endswith(".skill") Type guard
def is_editable_artifact_path(path: str) -> bool:
stripped = path.lstrip("/")
if not stripped.startswith("mnt/user-data/outputs/"):
return False
return ".skill/" not in stripped and not stripped.endswith(".skill") Try / catch
if resp.status_code == 415 and "Skill archives cannot be edited" in resp.text:
show_readonly_preview(path) # fall back to GET preview Prevention
- Hide .skill entries behind a read-only preview in artifact UIs
- Treat .skill as an opaque package: modify via skills endpoints, never byte-level editors
- When generating skill packs into outputs, name them clearly so users understand they are archives
When it happens
Trigger: PUT edit-artifact with a path such as 'mnt/user-data/outputs/packs/my.skill' or 'mnt/user-data/outputs/my.skill/SKILL.md' — any editable-prefix path that is inside or is a skill archive.
Common situations: Users trying to tweak a downloaded/generated skill pack from the artifacts panel, or an agent that saved a .skill bundle into outputs and the UI offers it for editing.
Related errors
- Skill archive member is too large to preview
- File '{internal_path}' not found in skill archive
- Symlinked artifacts cannot be edited
- Binary artifacts cannot be edited
- Only UTF-8 text artifacts can be edited
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/a776f34c82a8132f.
Report an issue: GitHub.