google/python-fire · error · ValueError

FindExecutableOnPath({0},...) failed because first argument

Error message

FindExecutableOnPath({0},...) failed because first argument must not have an extension.

What it means

FindExecutableOnPath refuses to search when extensions are disallowed and the given executable name already contains an extension (os.path.splitext yields a non-empty suffix). The function's contract is to locate a bare executable name and try allowed extensions itself; passing a pre-extensioned name would be ambiguous or redundant.

Source

Thrown at fire/console/files.py:98

    executable: The name of the executable to find.
    path: A list of directories to search separated by 'os.pathsep'.  If None
      then the system PATH is used.
    pathext: An iterable of file name extensions to use.  If None then
      platform specific extensions are used.
    allow_extensions: A boolean flag indicating whether extensions in the
      executable are allowed.

  Returns:
    The path of 'executable' (possibly with a platform-specific extension) if
    found and executable, None if not found.

  Raises:
    ValueError: if executable has a path or an extension, and extensions are
      not allowed, or if there's an internal error.
  """

  if not allow_extensions and os.path.splitext(executable)[1]:
    raise ValueError('FindExecutableOnPath({0},...) failed because first '
                     'argument must not have an extension.'.format(executable))

  if os.path.dirname(executable):
    raise ValueError('FindExecutableOnPath({0},...) failed because first '
                     'argument must not have a path.'.format(executable))

  if path is None:
    effective_path = _GetSystemPath()
  else:
    effective_path = path
  effective_pathext = (pathext if pathext is not None
                       else _PlatformExecutableExtensions(
                           platforms.OperatingSystem.Current()))

  return _FindExecutableOnPath(executable, effective_path,
                               effective_pathext)

View on GitHub (pinned to 716bbc23d7)

Solutions

  1. Strip the extension before calling: use os.path.splitext(name)[0].
  2. Pass allow_extensions=True if the name legitimately includes an extension.
  3. Call with just the base command name, e.g. 'git' not 'git.exe'.

Example fix

// before
FindExecutableOnPath('git.exe', allow_extensions=False)
// after
FindExecutableOnPath(os.path.splitext('git.exe')[0], allow_extensions=False)  # 'git'
Defensive patterns

Strategy: validation

Validate before calling

import os
if not allow_extensions and os.path.splitext(executable)[1]:
    executable = os.path.splitext(executable)[0]

Type guard

def is_bare_executable_name(name: str) -> bool:
    return os.path.splitext(name)[1] == ''

Try / catch

try:
    exe = files.FindExecutableOnPath(executable)
except ValueError as e:
    print(f'{e} — pass a bare command name'); sys.exit(2)

Prevention

When it happens

Trigger: FindExecutableOnPath('git.exe', allow_extensions=False) or FindExecutableOnPath('archive.tar') — any name whose splitext()[1] is non-empty while allow_extensions is False.

Common situations: Windows users habitually appending .exe; passing filenames copied from a directory listing; confusing this API with a plain file-existence check.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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