sqlalchemy/alembic · error · ValueError
{path} is not in the same subtree as {other}
Error message
{path} is not in the same subtree as {other} What it means
Raised inside path_relative_to (alembic/util/compat.py:88) when walk_up=True and the given path shares no common ancestor directory with 'other' — i.e. after walking every parent of 'other', path.relative_to still fails for all of them. This is Alembic's backport of pathlib's walk_up behavior; on paths with no shared root (e.g. different drives on Windows, or mismatched Path types) it gives up.
Source
Thrown at alembic/util/compat.py:88
) -> Path:
"""
Calculate the relative path of 'path' with respect to 'other',
optionally allowing 'path' to be outside the subtree of 'other'.
OK I used AI for this, sorry
"""
try:
return path.relative_to(other)
except ValueError:
if walk_up:
other_ancestors = list(other.parents) + [other]
for ancestor in other_ancestors:
try:
return path.relative_to(ancestor)
except ValueError:
continue
raise ValueError(
f"{path} is not in the same subtree as {other}"
)
else:
raise
def importlib_metadata_get(group: str) -> Sequence[EntryPoint]:
"""provide a facade for metadata.entry_points().
This is no longer a "compat" function as of Python 3.10, however
the function is widely referenced in the test suite and elsewhere so is
still in this module for compatibility reasons.
"""
return metadata.entry_points().select(group=group)
def formatannotation_fwdref(View on GitHub (pinned to 44fb345033)
Solutions
- Confirm both paths are under the same filesystem root; if on Windows, move both under the same drive letter.
- Avoid passing walk_up=True when the paths are known to be unrelated; compute the relationship manually instead.
- Use absolute, normalized paths resolved via Path.resolve() before comparison to eliminate symlink/junction ambiguity.
Example fix
# before: paths on different roots
rel = path_relative_to(Path('/mnt/data/x'), Path('/opt/app'), walk_up=True)
# after: ensure both share a common root, or compute manually
rel = Path('/opt/app/data/x').relative_to(Path('/opt/app')) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def safe_relative(path: Path, other: Path) -> Path:
path, other = path.resolve(), other.resolve()
try:
return path.relative_to(other)
except ValueError:
# only call path_relative_to(walk_up=True) when roots match
if path.anchor != other.anchor:
raise ValueError(f'{path} and {other} are on different roots')
from alembic.util.compat import path_relative_to
return path_relative_to(path, other, walk_up=True) Type guard
from pathlib import PurePath
def shares_root(a: PurePath, b: PurePath) -> bool:
return PurePath(a).anchor == PurePath(b).anchor Try / catch
from alembic.util.compat import path_relative_to
try:
rel = path_relative_to(path, other, walk_up=True)
except ValueError as e:
# fall back to absolute path string if no common subtree
rel = path Prevention
- Resolve both paths via Path.resolve() before comparing to eliminate symlink/junction noise.
- On Windows, keep project files and dependencies on the same drive letter.
- Prefer plain relative_to() when paths are expected to be nested.
When it happens
Trigger: Calling path_relative_to(path_a, path_b, walk_up=True) where path_a and path_b live on entirely disjoint roots (e.g. C:\proj vs D:\other on Windows, or a posix path vs a windows path in tests). Also reachable via Alembic internals that compute template/resource paths across different roots.
Common situations: Windows multi-drive setups where the migrations directory and the alembic package install are on different drive letters; cross-platform test suites that construct mixed-style Path objects; symlinks that resolve to a different filesystem root.
Related errors
- No suitable editor found. Please set the "EDITOR" or "VISUAL
- Can't find Python file %s
- Can't drop table in batch mode
- Constraint must have a name
- No such constraint: '%s'
AI-assisted analysis of sqlalchemy/alembic@44fb345033 (2026-08-04).
Data as JSON: /data/errors/7ed10cef8634a59f.json.
Report an issue: GitHub.