matplotlib/matplotlib · error · ValueError
Got unknown shape: {self._shape!r}
Error message
Got unknown shape: {self._shape!r} What it means
patches.FancyArrow(x, y, dx, dy, ...) draws the shaft plus head halves selected by its shape parameter, which may only be 'full', 'left', or 'right'. _get_path's geometry code falls through to raise ValueError(f"Got unknown shape: {self._shape!r}") for any other value, at construction/draw time.
Source
Thrown at lib/matplotlib/patches.py:1633
left_half_arrow += [head_length, 0]
# if the head starts at 0, shift up by another head length
if self._head_starts_at_zero:
left_half_arrow += [head_length / 2, 0]
# figure out the shape, and complete accordingly
if self._shape == 'left':
coords = left_half_arrow
else:
right_half_arrow = left_half_arrow * [1, -1]
if self._shape == 'right':
coords = right_half_arrow
elif self._shape == 'full':
# The half-arrows contain the midpoint of the stem,
# which we can omit from the full arrow. Including it
# twice caused a problem with xpdf.
coords = np.concatenate([left_half_arrow[:-1],
right_half_arrow[-2::-1]])
else:
raise ValueError(f"Got unknown shape: {self._shape!r}")
if distance != 0:
cx = self._dx / distance
sx = self._dy / distance
else:
# Account for division by zero
cx, sx = 0, 1
M = [[cx, sx], [-sx, cx]]
self.verts = np.dot(coords, M) + [
self._x + self._dx,
self._y + self._dy,
]
_docstring.interpd.register(
FancyArrow="\n".join(
(inspect.getdoc(FancyArrow.__init__) or "").splitlines()[2:]))
View on GitHub (pinned to b379c1b69e)
Solutions
- Use one of 'full' (default), 'left', or 'right'.
- Validate free-form input against the allowed set before constructing.
- For richer head styles (open heads, filled variants, mutation_scale), switch to FancyArrowPatch with arrowstyle, or ax.annotate.
- Check for typos — this is the most common single cause.
Example fix
# before arrow = patches.FancyArrow(0, 0, 1, 0.5, width=0.05, shape='both') # after arrow = patches.FancyArrow(0, 0, 1, 0.5, width=0.05, shape='full') # or richer styling: patches.FancyArrowPatch((0, 0), (1, 0.5), arrowstyle='<|-|>', mutation_scale=15)
Defensive patterns
Strategy: validation
Validate before calling
shape = shape if shape in ('full', 'left', 'right') else 'full'
arrow = patches.FancyArrow(x, y, dx, dy, shape=shape) Type guard
def is_valid_arrow_shape(s) -> bool:
return s in ('full', 'left', 'right') Prevention
- Whitelist user input to {'full', 'left', 'right'} before constructing FancyArrow.
- For advanced head styles use FancyArrowPatch(arrowstyle=...) or annotate, not shape strings.
- Watch for typos — 'ful' and 'both' are the usual offenders.
When it happens
Trigger: FancyArrow(0, 0, 1, 1, shape='both') or shape='halves'; typos like shape='ful'; passing head-orientation strings from other APIs (e.g. '<|-|>' annotation styles); passing None.
Common situations: Confusing FancyArrow's shape with annotate/FancyArrowPatch arrowstyle strings; exposing a user 'arrow head side' option without validation; copy-pasting from examples using different libraries (plotly's 'head' vocabulary).
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- shade must be between 0 and 1.
- `rotation_point` must be one of {'xy', 'center', (number, nu
- Parameter 'r' must be one or two floats.
- linestyles and positions are unequal sized sequences
- 'facecolor' or 'color' argument must be a valid color or seq
AI-assisted analysis of matplotlib/matplotlib@b379c1b69e (2026-08-21).
Data as JSON: /api/errors/34372b1f122abb16.
Report an issue: GitHub.