python/cpython · error

lost sys.stderr\n

Error message

lost sys.stderr\n

What it means

Printed by _PyErr_Display (Python/pythonrun.c) after print_exception_recursive fails and the fallback PyObject_Dump(value) is used. 'lost sys.stderr' means the exception could not be formatted and written to the error file through the normal machinery — typically because writing to sys.stderr itself raised (closed pipe, custom sys.stderr whose write failed) or unrecoverable MemoryError during formatting. The original exception is dumped in raw object form instead of a readable traceback.

Source

Thrown at Python/pythonrun.c:1197

         PyErr_FormatUnraisable(
             "Exception ignored in the internal traceback machinery");
     }
#endif
    PyErr_Clear();
    struct exception_print_context ctx;
    ctx.file = file;

    /* We choose to ignore seen being possibly NULL, and report
       at least the main exception (it could be a MemoryError).
    */
    ctx.seen = PySet_New(NULL);
    if (ctx.seen == NULL) {
        PyErr_Clear();
    }
    if (print_exception_recursive(&ctx, value) < 0) {
        PyErr_Clear();
        PyObject_Dump(value);
        fprintf(stderr, "lost sys.stderr\n");
    }
    Py_XDECREF(ctx.seen);

    /* Call file.flush() */
    if (_PyFile_Flush(file) < 0) {
        /* Silently ignore file.flush() error */
        PyErr_Clear();
    }
}

void
PyErr_Display(PyObject *unused, PyObject *value, PyObject *tb)
{
    PyObject *file;
    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
        PyObject *exc = PyErr_GetRaisedException();
        PyObject_Dump(value);
        fprintf(stderr, "lost sys.stderr\n");

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. If piping output, consume it fully or handle EPIPE: use `python script.py | head || true`, or trap SIGPIPE
  2. Restore/repair sys.stderr before the failure point; wrap custom stderr objects so write() never raises
  3. For MemoryError-driven cases, reduce recursion/exception-chain depth or raise memory limits

Example fix

# before
class BadStderr:
    def write(self, s): raise OSError('broken')
sys.stderr = BadStderr()
raise ValueError('boom')
# after
class SafeStderr:
    def write(self, s):
        try: return sys.__stderr__.write(s)
        except Exception: return 0
sys.stderr = SafeStderr()
raise ValueError('boom')
Defensive patterns

Strategy: fallback

Validate before calling

# make custom stderr writes non-raising before user code runs
import sys
class SafeStderr:
    def write(self, s):
        try:
            sys.__stderr__.write(s)
        except Exception:
            pass
        return len(s)
    def flush(self): pass
sys.stderr = SafeStderr()

Try / catch

# treat output loss as a signal, not a crash: check pipe status
# bash
set -o pipefail
python app.py | head || echo "output pipe closed early" >&2

Prevention

When it happens

Trigger: sys.stderr replaced by an object whose write/flush raises while an unhandled exception is being printed; sys.stderr attached to a closed pipe (e.g. python | head closing early); MemoryError while formatting a huge exception chain.

Common situations: `python script.py | head` where head exits first (SIGPIPE/EPIPE); user code or sitecustomize swapping sys.stderr for a broken wrapper; deeply recursive exception chains exhausting memory during display.

Related errors


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