python/cpython · error

pre-site failed:\n

Error message

pre-site failed:\n

What it means

Printed at the error label of run_presite (Python/pylifecycle.c) after any exception while processing the pre-site hook: splitting 'mod:func', importing the module, getting the attribute, or calling the function. The message 'pre-site failed:' is followed by the full traceback via _PyErr_Print. It is a hard error path — the hook did not run, and cleanup of partially built objects (mod_name, func_name, module) follows.

Source

Thrown at Python/pylifecycle.c:1346

            goto error;
        }

        PyObject *res = PyObject_CallNoArgs(func);
        Py_DECREF(func);
        if (res == NULL) {
            goto error;
        }
        Py_DECREF(res);
    }

    Py_DECREF(presite);
    Py_DECREF(mod_name);
    Py_XDECREF(func_name);
    Py_DECREF(module);
    return;

error:
    fprintf(stderr, "pre-site failed:\n");
    _PyErr_Print(tstate);

    Py_DECREF(presite);
    Py_XDECREF(mod_name);
    Py_XDECREF(func_name);
    Py_XDECREF(module);
}
#endif


static PyStatus
init_interp_main(PyThreadState *tstate)
{
    assert(!_PyErr_Occurred(tstate));

    PyStatus status;
    int is_main_interp = _Py_IsMainInterpreter(tstate->interp);
    PyInterpreterState *interp = tstate->interp;

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Check the printed traceback: fix the ImportError/AttributeError it names
  2. Ensure the presite module is importable pre-site (stdlib or early sys.path entry) — site-packages may not be available yet
  3. Use the exact 'mod' or 'mod:func' syntax; a leading ':' (pos <= 0) or missing func will land here

Example fix

# before
PYTHON_PRESITE=mymodule:main python app.py   # main() raises
# after
PYTHON_PRESITE=mymodule:safe_setup python app.py
Defensive patterns

Strategy: try-catch

Validate before calling

# verify the hook resolves before relying on it (same import rules apply)
python -c "import importlib; m,f='myhook:setup'.split(':'); getattr(importlib.import_module(m), f)"

Try / catch

# inside the presite function itself — never let exceptions escape
def setup():
    try:
        ...early instrumentation...
    except Exception:
        import sys; sys.__stderr__.write('presite hook degraded\n')

Prevention

When it happens

Trigger: Setting -X presite=modname or modname:funcname where modname is not importable, the function name does not exist on the module, or the function itself raises. Any failure between PyUnicode_Substring and the PyObject_Call of the hook.

Common situations: Debug/free-threaded workflows where PYTHON_PRESITE points at a module not on sys.path at that early stage; typos in the entry-point spec; hook code assuming site.py already ran.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/d918fac37c19fa4b. Report an issue: GitHub.