Fix SystemError: Parent Module Not Loaded for Relative Import

Quick answer: The parent-module-not-loaded SystemError occurs when a module with a relative import is executed without package context. Run it as python -m package.module from the parent directory, or use a consistent absolute package import in an installed project.

Python Pool infographic showing a package module failing when run as a file and succeeding when launched with python -m from its parent directory
Relative imports require package context; launching a module with python -m preserves that context while direct file execution often does not.

SystemError: Parent module not loaded, cannot perform relative import is an older Python import error that appears when a file tries to use a leading-dot import without the package context Python needs. The common modern wording is often ImportError: attempted relative import with no known parent package, but the root cause is the same: Python is running the file as a loose script instead of as a module inside a package. Modern Python usually reports the same missing package context as an attempted relative import with no known parent; Fix Python Attempted Relative Import Error shows the package-aware invocation.

The fix is usually to run the module from the project root with python -m package.module, add a proper package layout, or switch to absolute imports. Do not remove dots randomly. A relative import such as from .helpers import parse is valid only when Python knows the current package name.

The official Python documentation explains intra-package references, the -m command-line option, and the import system.

The error is not caused by a bad Python installation. It is caused by how the code is launched and how the files are arranged. This matters in editors, notebooks, command-line scripts, test runners, cron jobs, and deployed services because each environment can start from a different folder or run a different entry point.

Before changing imports, reproduce the error from a terminal with the same command your tool uses. If the terminal command works but the editor button fails, the editor is probably running a file path instead of a module name. If tests work but a scheduler fails, the scheduler may be starting from a different project folder.

A quick sys.path edit can appear to fix the traceback, but it often leaves the project fragile. Prefer a stable package command, an installed package, or a documented entry point. That way local development, tests, and production all import the same modules in the same way.

The examples below create small temporary packages so you can see the behavior safely.

Know The Modern Error Family

In Python 3, old IOError-style and import messages were cleaned up over time, but old posts, logs, and tools can still surface legacy wording. Treat this SystemError as an import-context problem.

print(IOError is OSError)
print(issubclass(FileNotFoundError, OSError))

text = "parent module not loaded, cannot perform relative import"
print("relative import" in text)

The exact exception name matters less than the import context. If the traceback points at a line like from .helpers import name, inspect the package layout and launch command first.

Use A Real Package Layout

A package should have a clear directory structure. The parent folder of the package is the place where you normally run the command.

from pathlib import Path

files = [
    Path("project/demo_pkg/__init__.py"),
    Path("project/demo_pkg/cli.py"),
    Path("project/demo_pkg/helpers.py"),
]

for item in files:
    print(item.as_posix())

Here, demo_pkg is the package. A file inside it can use from .helpers import label only when Python runs it with package context.

The __init__.py file can be empty. Its main role in this example is to make the package boundary obvious and compatible with older tooling.

Python Pool infographic showing package tree, module, parent package, dot import, and execution context
A relative import needs Python to know the module's package context.

See Why Direct File Execution Fails

Running a package file by path makes it behave like a standalone script. That removes the parent package information needed by a leading-dot import.

from pathlib import Path
from tempfile import TemporaryDirectory
import subprocess
import sys

with TemporaryDirectory() as folder:
    root = Path(folder)
    package = root / "demo_pkg"
    package.mkdir()
    (package / "__init__.py").write_text("", encoding="utf-8")
    (package / "helpers.py").write_text("def label():\n    return 'ready'\n", encoding="utf-8")
    (package / "cli.py").write_text("from .helpers import label\nprint(label())\n", encoding="utf-8")

    completed = subprocess.run([sys.executable, str(package / "cli.py")], cwd=root, text=True, capture_output=True)
    print(completed.returncode != 0)
    print("relative import" in completed.stderr)

This is the usual failure mode behind the old SystemError wording. The code inside the file may be correct, but the entry point is wrong.

Run The Module With -m

The -m option tells Python to run the file as a module inside its package.

from pathlib import Path
from tempfile import TemporaryDirectory
import subprocess
import sys

with TemporaryDirectory() as folder:
    root = Path(folder)
    package = root / "demo_pkg"
    package.mkdir()
    (package / "__init__.py").write_text("", encoding="utf-8")
    (package / "helpers.py").write_text("def label():\n    return 'ready'\n", encoding="utf-8")
    (package / "cli.py").write_text("from .helpers import label\nprint(label())\n", encoding="utf-8")

    completed = subprocess.run([sys.executable, "-m", "demo_pkg.cli"], cwd=root, text=True, capture_output=True)
    print(completed.returncode)
    print(completed.stdout.strip())

Run this command from the parent folder of demo_pkg. In an editor, look for a setting that runs a module name instead of a file path.

Check __package__ When Unsure

__package__ reveals whether Python sees the file as part of a package.

from pathlib import Path
from tempfile import TemporaryDirectory
import subprocess
import sys

with TemporaryDirectory() as folder:
    root = Path(folder)
    package = root / "demo_pkg"
    package.mkdir()
    (package / "__init__.py").write_text("", encoding="utf-8")
    (package / "cli.py").write_text("print(__name__)\nprint(__package__)\n", encoding="utf-8")

    direct = subprocess.run([sys.executable, str(package / "cli.py")], cwd=root, text=True, capture_output=True)
    module = subprocess.run([sys.executable, "-m", "demo_pkg.cli"], cwd=root, text=True, capture_output=True)

    print(direct.stdout.strip().splitlines())
    print(module.stdout.strip().splitlines())

Direct execution prints an empty package context. Module execution prints the package name, which is what a relative import needs.

Python Pool infographic comparing direct script execution with python -m package.module and loaded package context
Running with python -m gives the module a package-aware execution context for relative imports.

Use Absolute Imports When Appropriate

If a module is shared widely across the application, an absolute import can be clearer. The package root must still be on Python’s import path.

from pathlib import Path
from tempfile import TemporaryDirectory
import os
import subprocess
import sys

with TemporaryDirectory() as folder:
    root = Path(folder)
    package = root / "demo_pkg"
    package.mkdir()
    (package / "__init__.py").write_text("", encoding="utf-8")
    (package / "helpers.py").write_text("def label():\n    return 'ready'\n", encoding="utf-8")
    (package / "cli.py").write_text("from demo_pkg.helpers import label\nprint(label())\n", encoding="utf-8")

    env = {**os.environ, "PYTHONPATH": str(root)}
    completed = subprocess.run([sys.executable, str(package / "cli.py")], cwd=root, env=env, text=True, capture_output=True)
    print(completed.returncode)
    print(completed.stdout.strip())

For applications, prefer one consistent import style. Use python -m for package entry points, absolute imports for broad cross-package references, and relative imports for nearby modules that move together.

Also check the folder from which the command runs. If a scheduler or web server launches the script from another folder, an import that worked locally can fail in production. Make the launch command explicit and keep it documented with the project.

In short, the fix is to give Python package context. Run python -m package.module from the project root, keep __init__.py where your tooling expects it, and use absolute imports when a file is meant to run outside the package.

Understand Direct File Execution

python package/module.py treats the file as the main script and often leaves __package__ empty. A leading-dot import then has no parent package from which to resolve the target.

Python Pool infographic showing package root, absolute module path, imported symbol, and successful execution
An absolute import can be clearer when the package is installed or the project root is configured correctly.

Use The Module Entry Point

Run python -m package.module from the directory containing package. Python sets the package context while still executing the module as __main__, allowing relative imports to resolve.

Keep The Layout Importable

Use a clear top-level package, avoid ambiguous filenames, and configure the project for installation or an explicit source root. The working directory should not be the only reason an import works.

Choose Absolute Or Relative Imports

Relative imports are useful within a stable package; absolute imports can make dependencies clearer across a larger project. Either style requires the package to be importable in the execution environment.

Python Pool infographic testing __init__.py, working directory, package name, PYTHONPATH, and validation
Check package structure, execution command, working directory, package installation, and import path assumptions.

Compare IDE And Terminal Launches

An IDE may select a module launch mode and working directory automatically. Print the interpreter, cwd, __package__, __spec__, and sys.path when comparing environments, but remove debugging output afterward.

Test Packaging And Entry Points

Test python -m, the installed console command, the test runner, editable installs, and a built wheel. Include imports from sibling and parent packages so a deployment cannot regress to direct-file execution.

Use the official Python import system documentation and the python -m command documentation. Related Python Pool references include tests and configuration.

For related import debugging, compare package tests, environment configuration, and module paths before changing a relative import.

Frequently Asked Questions

Why does parent module not loaded happen?

Python is executing a module without the package context required to resolve its relative import, commonly because a package file was run directly.

How do I fix the relative import error?

Run the module from the package’s parent directory with python -m package.module and keep imports consistent with the package layout.

Should I change the relative import to an absolute import?

An absolute package import can be correct, but it still requires the project to be importable; changing syntax without fixing the execution context may only move the error.

Why does the code work in an IDE but not the terminal?

The IDE may set the working directory, module path, and launch mode differently; compare the interpreter, cwd, environment, and exact command used.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted