nexu-io/open-design · error · SystemExit
Configured uploadPath for participant {participant['name']}
Error message
Configured uploadPath for participant {participant['name']} does not exist: {source}. Fix the upload avatar path before preparing the bundle. What it means
Thrown by copy_avatar_assets() in prepare_chat_overlay_bundle.py when a participant's resolved uploadPath does not point at an existing file on disk. The script copies upload avatars into the bundle's public/ folder, so a missing source cannot be bundled. It fires during prepare, after the template has been copied but before chatSpec.ts is written; on failure the partial bundle is deleted.
Source
Thrown at skills/chat-motion-overlay/scripts/prepare_chat_overlay_bundle.py:96
def write_chat_spec_ts(spec: dict, output_dir: Path) -> None:
target = output_dir / "src" / "chatSpec.ts"
content = "export const chatSpec = " + json.dumps(spec, ensure_ascii=False, indent=2) + " as const;\n"
target.write_text(content, encoding="utf-8")
def remove_local_upload_paths(spec: dict) -> None:
for participant in spec["participants"]:
participant.pop("uploadPath", None)
def copy_avatar_assets(spec: dict, output_dir: Path) -> dict:
upload_sources: list[tuple[dict, Path]] = []
for participant in spec["participants"]:
upload_path = participant.get("uploadPath")
if upload_path:
source = Path(upload_path).expanduser().resolve()
if not source.exists():
raise SystemExit(
f"Configured uploadPath for participant {participant['name']} does not exist: {source}. "
"Fix the upload avatar path before preparing the bundle."
)
upload_sources.append((participant, source))
public_dir = output_dir / "public"
public_dir.mkdir(parents=True, exist_ok=True)
for preset_file in avatar_library_dir().glob("*.png"):
shutil.copy2(preset_file, public_dir / preset_file.name)
for participant, source in upload_sources:
target_name = f"{participant['id']}-upload{source.suffix.lower()}"
shutil.copy2(source, public_dir / target_name)
participant["uploadAsset"] = target_name
remove_local_upload_paths(spec)
return spec
def main() -> None:
args = parse_args()View on GitHub (pinned to 5be4028344)
Solutions
- Verify the uploadPath exists with `ls -l <path>` from the same cwd the script runs in.
- Use an absolute path (or a path starting with ~) for uploadPath to avoid cwd ambiguity; the script runs Path(...).expanduser().resolve().
- If the avatar is gone, regenerate or pick a preset avatar and switch avatarMode accordingly.
Example fix
// before
{"participants": {"老婆": {"uploadPath": "avatars/me.png"}}} // not found from skill cwd
// after
{"participants": {"老婆": {"uploadPath": "~/projects/avatars/me.png"}}} Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def assert_uploads_exist(spec: dict) -> None:
missing = []
for p in spec.get("participants", []):
up = p.get("uploadPath")
if up and not Path(up).expanduser().resolve().exists():
missing.append((p["name"], up))
if missing:
raise SystemExit(f"upload avatars missing: {missing}") Prevention
- Use absolute or ~-prefixed paths for uploadPath to avoid cwd ambiguity.
- Verify avatar files exist immediately before running prepare_chat_overlay_bundle.py.
When it happens
Trigger: Run prepare_chat_overlay_bundle.py with avatarMode in {upload, mixed} and a participant uploadPath that does not exist (wrong path, typo, relative path resolved against the wrong cwd, or file deleted). The run_test_matrix.py case 'invalid_upload_missing_file' reproduces this.
Common situations: Relative uploadPath interpreted against a different cwd than expected; a path copied from another machine; the avatar file was moved or deleted after the config was written; ~ expansion differences.
Related errors
- Refusing to use dangerous output directory: {output_dir}. Ch
- Refusing to overwrite unmanaged output directory: {output_di
- Output directory already exists: {output_dir}. Use --force t
- avatarMode=preset does not allow uploadPath for participant
- avatarMode=upload requires uploadPath for participant {speak
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/d402fbd7505f2feb.
Report an issue: GitHub.