sqlalchemy/alembic · error · ValueError

is not in the same subtree as

Error message

{path} is not in the same subtree as {other}

What it means

Raised by path_relative_to (the Python <3.12 fallback in alembic/util/compat.py:88) when walk_up=True and the given path is not relative to any ancestor of 'other'. This means the two paths share no common subtree — they live on entirely different filesystem roots or diverge at the root level. The function walks up through other.parents attempting a match and fails.

Solutions

  1. Ensure the migrations directory and the config file (alembic.ini or pyproject.toml) are on the same filesystem root.
  2. Use an absolute path for script_location in the config file to bypass relative path computation.
  3. On Windows, verify both paths are on the same drive letter.
  4. Move the config file or migrations directory so one is within the other's subtree.

Example fix

# before (alembic.ini on C:, migrations on D:)
alembic init D:\migrations

# after
# keep config and migrations on the same drive
alembic init C:\project\migrations
Defensive patterns

Strategy: validation

Validate before calling

import os

def paths_share_root(path1, path2):
    p1 = os.path.abspath(path1)
    p2 = os.path.abspath(path2)
    return os.path.commonpath([p1, p2]) not in ('', '/') or os.path.splitdrive(p1)[0] == os.path.splitdrive(p2)[0]

Try / catch

from alembic.util.exc import CommandError

try:
    command.init(config, directory)
except CommandError as e:
    if "not in the same subtree" in str(e):
        # use absolute path for script_location instead
        print("Use absolute path or move config and migrations to same root")
    raise

Prevention

When it happens

Trigger: Calling compat.path_relative_to(path, other, walk_up=True) where path and other have no common ancestor (compat.py:82-90). In production this is called from command.py:91-103 during 'alembic init' to compute the script_location relative to the config file — fails if the migrations directory and config file are on different drives (Windows) or mount points.

Common situations: On Windows, placing alembic.ini on C: and the migrations directory on D:. Symlinks that resolve to different roots. Running 'alembic init' with a directory path that is not under the config file's parent tree. Unusual mount layouts in containers where /config and /migrations are separate roots.

Related errors


AI-assisted analysis of sqlalchemy/alembic@5551b5d35f (2026-08-11). Data as JSON: /api/errors/7ed10cef8634a59f. Report an issue: GitHub.

Appendix: 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 5551b5d35f)