{"record":{"id":"39b9f26df119f70c","repo":"affaan-m/ECC","slug":"cannot-upload-file-does-not-exist-p-39b9f2","errorCode":null,"errorMessage":"cannot upload, file does not exist: {p}","messagePattern":"cannot upload, file does not exist: (.+?)","errorType":"exception","errorClass":"FalError","httpStatus":null,"severity":"error","filePath":"skills/taste-distillation/scripts/taste/falapi.py","lineNumber":300,"sourceCode":"\n\ndef _cache_key(path: Path) -> tuple[str, int, int]:\n    st = path.stat()\n    return (str(path.resolve()), st.st_mtime_ns, st.st_size)\n\n\ndef upload(path: str | Path) -> str:\n    \"\"\"Upload a local file and return its URL, memoized per (path, mtime, size).\n\n    apply.py reuses the same handful of stills across every shot in a run and\n    across concurrent workers; without this cache each of those becomes a\n    redundant multi-megabyte POST.\n    \"\"\"\n    if not is_dry_run():\n        require_live()\n    p = Path(path)\n    if not p.exists():\n        raise FalError(f\"cannot upload, file does not exist: {p}\")\n\n    key = _cache_key(p)\n    with _UPLOAD_LOCK:\n        hit = _UPLOAD_CACHE.get(key)\n    if hit and (is_dry_run() == hit.startswith(DRY_RUN_HOST + \"/\")):\n        log.debug(\"upload cache hit: %s\", p.name)\n        return hit\n\n    if is_dry_run():\n        url = f\"{DRY_RUN_HOST}/uploads/{_digest(str(key))}/{p.name}\"\n        log.info(\"[dry-run] would upload %s (%d bytes) -> %s\", p, key[2], url)\n    else:\n        api_key()\n        try:\n            url = _fal().upload_file(str(p))\n        except Exception:\n            raise FalError(\"fal upload failed; provider details omitted\") from None\n        log.info(\"uploaded %s -> %s\", p.name, safe_url(url))","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-distillation/scripts/taste/falapi.py#L282-L318","documentation":"FalError raised by upload() when the local file path passed for upload does not exist on disk. Checked before any provider call, and before consulting the upload cache, so no network activity happens. The message includes the offending path.","triggerScenarios":"Calling upload(path) (or upload_many) in live mode with a path whose Path(path).exists() is False — e.g. a frame extraction step failed earlier, a relative path resolved from the wrong working directory, or a typo'd filename.","commonSituations":"Pipeline stage that produces the image ran but wrote elsewhere; passing an output URL instead of a local file; deleted temp files between steps; running from a different CWD than expected.","solutions":["Verify the file exists before uploading: Path(path).exists() or os.path.isfile(path)","Print/inspect the absolute path (Path(path).resolve()) to spot CWD or relative-path mistakes","Fix the upstream step that was supposed to create the file","If you already have a hosted URL, skip upload and pass the URL directly"],"exampleFix":"// before\nurl = falapi.upload(\"frames/front.png\")  # FalError: cannot upload, file does not exist\n// after\nfrom pathlib import Path\np = Path(\"frames/front.png\")\nif not p.exists():\n    raise FileNotFoundError(f\"expected frame missing: {p.resolve()}\")\nurl = falapi.upload(str(p))","handlingStrategy":"validation","validationCode":"from pathlib import Path\np = Path(path)\nif not p.is_file():\n    raise FileNotFoundError(f\"upload source missing: {p.resolve()}\")","typeGuard":null,"tryCatchPattern":"try:\n    url = falapi.upload(path)\nexcept falapi.FalError as e:\n    if \"does not exist\" in str(e):\n        print(f\"Check path/CWD: {Path(path).resolve()}\")","preventionTips":["Resolve and print absolute paths before uploading","Confirm the upstream step that creates the file actually succeeded","Run pipeline steps from a consistent working directory","Don't pass hosted URLs to upload() — pass URLs straight to the API call"],"tags":["python","filesystem","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}