Textualize/rich · error · ValueError

Value for 'trace' required if not called in except: block

Error message

Value for 'trace' required if not called in except: block

What it means

Traceback's constructor accepts an optional trace= argument (pre-extracted StackTrace). When trace is None it falls back to sys.exc_info() to capture the in-flight exception; if there is no active exception (exc_type is None) it cannot build anything and raises ValueError('Value for \"trace\" required if not called in except: block').

Source

Thrown at rich/traceback.py:318

        code_width: Optional[int] = 88,
        extra_lines: int = 3,
        theme: Optional[str] = None,
        word_wrap: bool = False,
        show_locals: bool = False,
        locals_max_length: int = LOCALS_MAX_LENGTH,
        locals_max_string: int = LOCALS_MAX_STRING,
        locals_max_depth: Optional[int] = None,
        locals_hide_dunder: bool = True,
        locals_hide_sunder: bool = False,
        locals_overlow: Optional[OverflowMethod] = None,
        indent_guides: bool = True,
        suppress: Iterable[Union[str, ModuleType]] = (),
        max_frames: int = 100,
    ):
        if trace is None:
            exc_type, exc_value, traceback = sys.exc_info()
            if exc_type is None or exc_value is None or traceback is None:
                raise ValueError(
                    "Value for 'trace' required if not called in except: block"
                )
            trace = self.extract(
                exc_type, exc_value, traceback, show_locals=show_locals
            )
        self.trace = trace
        self.width = width
        self.code_width = code_width
        self.extra_lines = extra_lines
        self.theme = Syntax.get_theme(theme or "ansi_dark")
        self.word_wrap = word_wrap
        self.show_locals = show_locals
        self.indent_guides = indent_guides
        self.locals_max_length = locals_max_length
        self.locals_max_string = locals_max_string
        self.locals_max_depth = locals_max_depth
        self.locals_hide_dunder = locals_hide_dunder
        self.locals_hide_sunder = locals_hide_sunder

View on GitHub (pinned to 9d8f9a372c)

Solutions

  1. Construct Traceback inside the except: block, or pass trace=Traceback.extract(*sys.exc_info()) captured earlier.
  2. In helpers, guard with sys.exc_info()[0] is not None before constructing, else render a generic message.
  3. Store exc_info at capture time: tb_info = sys.exc_info(); later Traceback(trace=Traceback.extract(*tb_info)).

Example fix

# before
def fmt():
    return Traceback()  # ValueError when no active exception

# after
import sys
from rich.traceback import Traceback
def fmt():
    if sys.exc_info()[0] is None:
        return Text('no active exception')
    return Traceback(show_locals=True)
Defensive patterns

Strategy: validation

Validate before calling

import sys
from rich.traceback import Traceback

def current_traceback(**kw):
    if sys.exc_info()[0] is None:
        return None  # caller renders a fallback message
    return Traceback(**kw)

Try / catch

try:
    tb = Traceback(show_locals=True)
except ValueError:
    tb = None  # not in an except block

Prevention

When it happens

Trigger: Constructing Traceback() at module level or in normal flow (no except: block active); saving a Traceback(...) factory call in a helper invoked outside the handler; calling Traceback(None) explicitly outside except. Inside except, or with trace= supplied, it works.

Common situations: Building a reusable 'format last error' utility that may be called when no exception is active; deferred rendering — creating Traceback in one function but raising/catching elsewhere; testing traceback rendering outside an exception context.

Related errors


AI-assisted analysis of Textualize/rich@9d8f9a372c (2026-08-15). Data as JSON: /api/errors/2d87c014f6600186. Report an issue: GitHub.