google/python-fire · error · OSError

Unable to load module from specified path.

Error message

Unable to load module from specified path.

What it means

After the path exists, fire builds a module spec with importlib.util.spec_from_file_location. If Python cannot produce a spec or loader for that file, fire raises OSError('Unable to load module from specified path.'). This means the file is on disk but is not importable as a Python module (wrong type, unreadable, or an unrecognized extension/format for the loader).

Source

Thrown at fire/__main__.py:64

    path (str): the path to the file to be imported.

  Raises:
    IOError: if the given file does not exist or importlib fails to load it.

  Returns:
    Tuple[ModuleType, str]: returns the imported module and the module name,
      usually extracted from the path itself.
  """

  if not os.path.exists(path):
    raise OSError('Given file path does not exist.')

  module_name = os.path.basename(path)

  spec = util.spec_from_file_location(module_name, path)

  if spec is None or spec.loader is None:
    raise OSError('Unable to load module from specified path.')

  module = util.module_from_spec(spec)  # pylint: disable=no-member
  spec.loader.exec_module(module)

  return module, module_name


def import_from_module_name(module_name):
  """Imports a module and returns it and its name."""
  module = importlib.import_module(module_name)
  return module, module_name


def import_module(module_or_filename):
  """Imports a given module or filename.

  If the module_or_filename exists in the file system and ends with .py, we
  attempt to import it. If that import fails, try to import it as a module.

View on GitHub (pinned to 716bbc23d7)

Solutions

  1. Confirm the target is a plain .py source file, not a data/config or compiled file.
  2. Check read permissions on the file (`ls -l`, `chmod`).
  3. Rename the file to end in .py if it is Python source with the wrong extension.
  4. Import the module by dotted name instead of by file path.

Example fix

// before
python -m fire ./script.txt serve
// after
mv script.txt script.py && python -m fire ./script.py serve
Defensive patterns

Strategy: validation

Validate before calling

import os
path = './script.py'
if os.path.exists(path) and (not os.path.isfile(path) or not os.access(path, os.R_OK)):
    raise SystemExit(f'{path} exists but is not a readable file')

Type guard

def is_importable_source(p: str) -> bool:
    return os.path.isfile(p) and p.endswith('.py') and os.access(p, os.R_OK)

Try / catch

try:
    module, name = fire_import.import_from_file_path(path)
except OSError as e:
    print(f'Cannot load module from {path}: {e}'); sys.exit(2)

Prevention

When it happens

Trigger: import_from_file_path is given an existing file whose extension/content importlib cannot map to a loader — e.g. a .pyc-less stub, an empty or unreadable file, or a non-.py file that still exists and passes the existence check.

Common situations: Pointing python -m fire at a config file, data file, or compiled artifact instead of a .py source file; file permission problems; files with odd extensions like .py.bak or .txt.

Related errors


AI-assisted analysis of google/python-fire@716bbc23d7 (2026-08-28). Data as JSON: /api/errors/f1a9f6ee2cb0e362. Report an issue: GitHub.