From 14e84b6ce2ec7b79b738b709cab9902a6b114fcd Mon Sep 17 00:00:00 2001 From: "tao.chen" <93983997+taochen-ct@users.noreply.github.com> Date: Tue, 4 Aug 2026 13:05:18 +0800 Subject: [PATCH] fix: path error --- backend/src/backend/scripts.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/backend/src/backend/scripts.py b/backend/src/backend/scripts.py index 9d099dd..7f03d51 100644 --- a/backend/src/backend/scripts.py +++ b/backend/src/backend/scripts.py @@ -103,13 +103,22 @@ def safe_script_name(value: str, script_type: str) -> str: def _jupyter_path(script_type: str, script_id: str) -> str: """Return the in-Jupyter path used for a script. - The path is ``notebooks/{script_id}.{ext}`` — deterministic and - collision-free because ``script_id`` is a fresh ULID. The user's - ``script_name`` is kept on the Scripts row as a display label only; - the on-disk filename is owned by the database. + The path is ``{script_id}.{ext}`` — deterministic and + collision-free because ``script_id`` is a fresh ULID. Jupyter's + contents API treats the suffix after ``/api/contents/`` as a path + relative to its ``--notebook-dir`` (the workspace root), so a + ``notebooks/`` prefix here would push the file into a non-existent + ``notebooks/`` subdir on disk. The user's ``script_name`` is kept on + the Scripts row as a display label only; the on-disk filename is + owned by the database. + + The ``/notebooks/`` segment in the user's browser URL + (``/jupyter//notebooks/.ipynb``) is jupyter's URL route + for the editor view, not a filesystem path — jupyter routes that + URL to the file at the workspace root. """ ext = ".ipynb" if script_type == "notebook" else ".py" - return f"notebooks/{script_id}{ext}" + return f"{script_id}{ext}" def validate_script_content(content: str, script_type: str) -> bytes: