Skip to content

fix: bundle code reached through a symlinked root (FLYTE-SDK-7E) - #1441

Open
EngHabu wants to merge 1 commit into
mainfrom
fix/sentry-7e-symlinked-root
Open

fix: bundle code reached through a symlinked root (FLYTE-SDK-7E)#1441
EngHabu wants to merge 1 commit into
mainfrom
fix/sentry-7e-symlinked-root

Conversation

@EngHabu

@EngHabu EngHabu commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

What

flyte deploy aborts with a raw ValueError out of pathlib when the bundle root is reached through a symlink (FLYTE-SDK-7E, release 2.6.0):

ValueError: '/tmp/flyte2-smoke.py' is not in the subpath of '/private/tmp'
  flyte/_code_bundle/_utils.py:198 in ls_files

Why

On macOS /tmp is a symlink to /private/tmp. The bundle root resolves to /private/tmp, but the loaded module's __file__ still reads /tmp/task.py.

_is_user_file checks containment on resolved paths, so the file is correctly accepted — but discovery returns it with its original spelling, which is not a literal subpath of the root. ls_files then takes it relative to the root and raises.

The crash is only the visible half. create_bundle derives tar arcnames with os.path.relpath, which is purely lexical: the same path yields ../link/task.py, trips the existing outside-the-root guard, and the file is silently dropped. A run that got past the ValueError would upload an empty bundle and fail on the cluster with ModuleNotFoundError instead. Verified both halves on main — the tarball comes back empty.

How

Rebase discovered paths onto the root, so containment stays resolved-based while the returned path keeps the source_path prefix that everything downstream (ls_files's digest, print_ls_tree, create_bundle's arcnames) expects. This mirrors what the additional_files branch already does for include paths.

Two deliberate constraints:

  • Paths already spelled as literal subpaths are left untouched. A symlink inside the root that legitimately points outside it (.venv/bin/python -> /usr/bin/python3) must keep its in-root spelling — create_bundle documents that it relies on this and avoids resolve() for exactly that reason. Pinned by a regression test.
  • A file still outside the root after resolving means the configured root doesn't contain the code. That's user configuration, not an SDK bug, so it now raises CodeBundleError naming the root and pointing at --root-dir, instead of leaking a raw pathlib ValueError into crash reporting.

No digest change for setups that work today: the only paths whose spelling changes are the ones that previously crashed.

Tests

4 tests in tests/flyte/code_bundle/test_code_bundle.py; 3 verified failing on main. The 4th is the .venv/bin/python guard, which passes on both sides by design — it exists to catch a regression this change could otherwise introduce.

Full tests/flyte: 3597 passed, 7 failed — all 7 fail identically on clean main in this environment.

fixes FLYTE-SDK-7E

`flyte deploy` aborted with a raw ValueError out of pathlib when the bundle root
was reached through a symlink:

    ValueError: '/tmp/flyte2-smoke.py' is not in the subpath of '/private/tmp'

On macOS `/tmp` is a symlink to `/private/tmp`, so the root resolves to
`/private/tmp` while the loaded module's `__file__` still reads `/tmp/task.py`.
`_is_user_file` checks containment on *resolved* paths, so the file is correctly
accepted, but discovery returns it with its original spelling — which is not a
literal subpath of the root. `ls_files` then takes it relative to the root and
raises.

The crash is only the visible half. `create_bundle` derives tar arcnames with
`os.path.relpath`, which is lexical: the same path yields `../link/task.py`,
trips the outside-the-root guard, and the file is *silently dropped*. A run that
got past the ValueError would upload an empty bundle and fail on the cluster
with ModuleNotFoundError instead.

Rebase discovered paths onto the root, so containment stays resolved-based while
the returned path keeps the `source_path` prefix that everything downstream
expects. This mirrors what the `additional_files` branch already does for
include paths. Paths that are already literal subpaths are left untouched — a
symlink *inside* the root that legitimately points outside it (`.venv/bin/python`)
must keep its in-root spelling, which `create_bundle` relies on.

A file that is still outside the root after resolving means the configured root
does not contain the code, so it now raises `CodeBundleError` naming the root and
pointing at `--root-dir`, instead of leaking a raw pathlib ValueError to Sentry.

fixes FLYTE-SDK-7E

Signed-off-by: Haytham Abuelfutuh <haytham@afutuh.com>
@EngHabu EngHabu added the sentry-fix Fix for an issue surfaced by Sentry label Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sentry-fix Fix for an issue surfaced by Sentry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant