Skip to content

Rename workspace objects with names illegal as local files in export-dir#5655

Merged
radakam merged 9 commits into
mainfrom
cli-5171-fix-workspace-export-dir-new-notebook
Jun 23, 2026
Merged

Rename workspace objects with names illegal as local files in export-dir#5655
radakam merged 9 commits into
mainfrom
cli-5171-fix-workspace-export-dir-new-notebook

Conversation

@radakam

@radakam radakam commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Why

A UI-created notebook is named like New Notebook 2026-05-04 13:54:24. The : is legal on Linux/macOS but illegal on Windows, so os.Create fails with ERROR_INVALID_NAME and the whole recursive export aborts on that one file.

Changes

  • export_dir.go: instead of aborting, sanitize the offending name (replace characters illegal in a local filename with _), export the object under the legal name, and emit a Warn: line so the rename is visible. Only ERROR_INVALID_NAME is handled this way — permission/disk/missing-path errors still propagate, so we never silently misplace files on real failures.
  • Sanitization and detection are build-tagged (export_dir_windows.go / export_dir_other.go) to avoid err.Error() string-matching and stay cross-platform; ERROR_INVALID_NAME has no portable Go sentinel. On non-Windows platforms sanitizeLocalName is a no-op (the only bytes illegal in a filename, / and NUL, can't appear in a workspace object name).
  • libs/testserver: added a fake WorkspaceList handler so the imported notebook is actually listed and exported.
  • Changelog entry added.

Changes to acceptance harness

  • The test runs on all OSes; behavior legitimately differs per platform (renamed-with-warning on Windows, exported as-is on Linux/macOS), so the golden output is split into per-OS leaf tests (posix/ and windows/), each GOOS-gated with its own captured output.

Tests

  • Acceptance (export-dir-illegal-filename/): on Windows the object is exported as New Notebook a_b.py with a Warn: line and the export completes; on Linux/macOS the : is legal so it exports unchanged. The fixture uses a plain New Notebook a:b name so the acceptance timestamp redaction doesn't obscure the golden (the real workspace export-dir failing on new notebook #5171 trigger is the auto-generated New Notebook <timestamp> name).
  • Unit (export_dir_windows_test.go): TestIsInvalidLocalNameError asserts the narrow contract — only ERROR_INVALID_NAME is handled; ErrPermission/ErrNotExist/generic/nil are not. TestSanitizeLocalName covers reserved-character replacement and leaves legal names untouched.

Fixes issue #5171.

Reproduces #5171: `workspace export-dir` aborts on Windows
when a notebook name contains a ':' (e.g. an untitled "New Notebook
<timestamp>"), because the colon is illegal in a local Windows filename
and os.Create fails. The name is legal on Linux/macOS, so the test is
gated to Windows via GOOS.

output.txt is intentionally omitted: the golden cannot be generated on a
non-Windows machine, so the Windows CI leg will surface the real output
to commit verbatim.
@radakam radakam temporarily deployed to test-trigger-is June 18, 2026 17:35 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 18, 2026 17:35 — with GitHub Actions Inactive
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: ce5e23d

Run: 28027851903

Env 🟨​KNOWN ✅​pass 🙈​skip Time
🟨​ aws linux 1 216 99 3:20
🟨​ aws windows 1 218 97 2:39
🟨​ aws-ucws linux 1 297 18 3:44
🟨​ aws-ucws windows 1 299 16 3:46
🟨​ azure linux 1 216 98 3:31
🟨​ azure windows 1 218 96 2:40
🟨​ azure-ucws linux 1 299 15 4:09
🟨​ azure-ucws windows 1 301 13 3:35
🟨​ gcp linux 1 215 100 3:09
🟨​ gcp windows 1 217 98 2:31
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K 🟨​K

Captured verbatim from the Windows CI run of the test added in the
previous commit. Documents the current (buggy) behavior of #5171:
export-dir aborts on Windows when a notebook name contains ':'.
@radakam radakam temporarily deployed to test-trigger-is June 18, 2026 19:17 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 18, 2026 19:17 — with GitHub Actions Inactive
A workspace object name can be illegal as a local filename (e.g. the ':'
in an untitled "New Notebook 2026-05-04 13:54:24" on Windows), which made
os.Create fail and abort the entire export. Skip such files with a
warning and continue, matching the existing skip paths for non-exportable
and oversized objects.

Detection uses a build-tagged helper checking the Windows
ERROR_INVALID_NAME code; on other platforms no filename character (other
than '/' and NUL, which cannot appear in a workspace object name) is
illegal, so it is a no-op.

Flips the Windows-gated acceptance test from asserting the abort to
expecting skip-with-warning. Fixes #5171.
@radakam radakam temporarily deployed to test-trigger-is June 18, 2026 19:31 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 18, 2026 19:31 — with GitHub Actions Inactive
Locks in the narrow contract that only the Windows ERROR_INVALID_NAME
error is treated as skippable, while permission, not-exist, generic, and
nil errors are not. The acceptance test only exercises the positive
(invalid-name) path, so this guards against accidentally broadening the
check and silently dropping files on real I/O failures.
@radakam radakam temporarily deployed to test-trigger-is June 18, 2026 19:38 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 18, 2026 19:38 — with GitHub Actions Inactive
@radakam radakam marked this pull request as ready for review June 19, 2026 06:08
Comment thread acceptance/cmd/workspace/export-dir-illegal-filename/test.toml Outdated
Comment thread acceptance/cmd/workspace/export-dir-illegal-filename/test.toml Outdated
The test reproducing #5171 was gated to Windows only because a
':' in the notebook name is illegal as a local filename on Windows but legal on
Linux/macOS, so export-dir skips it there and exports it everywhere else.

Run it on every OS and capture the divergent output in out.<goos>.txt. Teach the
acceptance runner to compare only the current OS's out.<goos>.txt and skip the
others (extending the existing variant-skip machinery), since otherwise the
non-current goldens would fail as "Missing output file".

Add a fake WorkspaceList handler so the imported notebook is listed and actually
exported, replacing the hardcoded [[Server]] list stub.
@radakam radakam temporarily deployed to test-trigger-is June 19, 2026 12:56 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 19, 2026 12:56 — with GitHub Actions Inactive
@shreyas-goenka shreyas-goenka self-requested a review June 19, 2026 13:26
…r GOOS filtering

Revert the per-GOOS output filtering added to the acceptance runner
(osVariants / preparePathFilter) and instead express the OS-specific behaviour
with two GOOS-gated leaf tests that share a single _script and notebook fixture:

  export-dir-illegal-filename/
    _script        # import + export-dir, shared by both leaves
    notebook.py    # shared fixture, referenced via $TESTDIR/../notebook.py
    posix/         # GOOS.windows = false  -> notebook exported
    windows/       # GOOS.{linux,darwin} = false -> skipped with a warning

The ':' in the notebook name is legal on Linux/macOS but illegal as a local
Windows filename, so export-dir skips it on Windows (#5171). The
two captured outputs differ, but everything else is shared, so the leaves only
carry their GOOS gate and golden. This keeps OS knowledge out of the shared
acceptance runner.
@radakam radakam temporarily deployed to test-trigger-is June 22, 2026 06:15 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 22, 2026 06:15 — with GitHub Actions Inactive
@radakam radakam changed the title temp: add Windows reproduction for export-dir on illegal notebook name Skip workspace objects with names illegal as local files in export-dir Jun 22, 2026
…tead of skipping

Previously export-dir skipped workspace objects whose names are not legal
local filenames (e.g. the ':' in "New Notebook 2026-05-04 13:54:24" on
Windows). Skipping silently dropped the file. Now the object is exported
under a sanitized name (illegal characters replaced with '_') and a
warning is emitted, so the content is preserved.

Adds a build-tagged sanitizeLocalName helper (Windows replaces the
reserved set plus control characters; no-op elsewhere) and a unit test
covering it. Flips the Windows-gated acceptance golden from skip to
rename-with-warning. Relates to #5171.
@radakam radakam temporarily deployed to test-trigger-is June 22, 2026 13:40 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 22, 2026 13:40 — with GitHub Actions Inactive
Comment thread acceptance/cmd/workspace/export-dir-illegal-filename/windows/output.txt Outdated
Comment thread cmd/workspace/workspace/export_dir_windows.go Outdated
Rename the fixture notebook to "New Notebook a:b" so the acceptance
timestamp redaction no longer applies and the golden stays literal.
Drop the unreachable control-character branch in sanitizeLocalName,
since workspace object names cannot contain control characters.
@radakam radakam temporarily deployed to test-trigger-is June 23, 2026 12:00 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 23, 2026 12:00 — with GitHub Actions Inactive
@radakam radakam enabled auto-merge June 23, 2026 12:09
A single ':' is the Windows alternate-data-stream separator, so
os.Create("New Notebook a:b.py") silently succeeds (writing stream
"b.py") instead of failing with ERROR_INVALID_NAME, leaving the Windows
golden unreproducible. Real #5171 names ("13:54:24") fail because they
contain two colons, which makes the stream type invalid. Switch the
fixture to "a:b:c" so it genuinely triggers the rename-with-warning path
on Windows, matching the unit test, while staying clear of the timestamp
redaction.
@radakam radakam changed the title Skip workspace objects with names illegal as local files in export-dir Rename workspace objects with names illegal as local files in export-dir Jun 23, 2026
@radakam radakam temporarily deployed to test-trigger-is June 23, 2026 12:56 — with GitHub Actions Inactive
@radakam radakam temporarily deployed to test-trigger-is June 23, 2026 12:56 — with GitHub Actions Inactive
@radakam radakam disabled auto-merge June 23, 2026 12:58
@radakam radakam added this pull request to the merge queue Jun 23, 2026
Merged via the queue into main with commit d8a33b9 Jun 23, 2026
23 checks passed
@radakam radakam deleted the cli-5171-fix-workspace-export-dir-new-notebook branch June 23, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants