pypa/pip · error · ValueError
Unknown: %r
Error message
Unknown: %r
What it means
Raised as ValueError by Sequencer.get_steps when the requested final node is not known to the sequencer — it is not in _preds, _succs, or _nodes (is_step() returns False). get_steps performs a topological walk backward from the final node, so an unknown final makes the walk impossible. This is the public-facing guard against asking for an ordering anchored on a node that was never added.
Source
Thrown at src/pip/_vendor/distlib/util.py:1133
def remove(self, pred, succ):
assert pred != succ
try:
preds = self._preds[succ]
succs = self._succs[pred]
except KeyError: # pragma: no cover
raise ValueError('%r not a successor of anything' % succ)
try:
preds.remove(pred)
succs.remove(succ)
except KeyError: # pragma: no cover
raise ValueError('%r not a successor of %r' % (succ, pred))
def is_step(self, step):
return (step in self._preds or step in self._succs or step in self._nodes)
def get_steps(self, final):
if not self.is_step(final):
raise ValueError('Unknown: %r' % final)
result = []
todo = []
seen = set()
todo.append(final)
while todo:
step = todo.pop(0)
if step in seen:
# if a step was already seen,
# move it to the end (so it will appear earlier
# when reversed on return) ... but not for the
# final step, as that would be confusing for
# users
if step != final:
result.remove(step)
result.append(step)
else:
seen.add(step)
result.append(step)View on GitHub (pinned to f399c37189)
Solutions
- Ensure the final node is added with add_node() (or implied via add edges) before calling get_steps.
- Guard: if sequencer.is_step(final): before get_steps.
- Verify node names against the set of known steps before querying.
Example fix
# before
order = seq.get_steps('build')
# after
if seq.is_step('build'):
order = seq.get_steps('build') Defensive patterns
Strategy: validation
Validate before calling
def safe_get_steps(seq, final):
if seq.is_step(final):
return seq.get_steps(final)
return None Type guard
def is_known_step(seq, node) -> bool:
return seq.is_step(node) Try / catch
try:
order = seq.get_steps(final)
except ValueError as e:
if 'Unknown' in str(e):
order = [] Prevention
- Call is_step(final) before get_steps.
- Ensure all nodes are added via add_node/add before querying.
When it happens
Trigger: Calling Sequencer().get_steps('final') without add_node('final'); get_steps on a node removed via remove_node before the ordering query; typo in the final node name.
Common situations: Querying an ordering before the graph is fully built; using a target node name from config that doesn't match any added node; post-cleanup queries referencing removed nodes.
Related errors
- %r not a successor of anything
- %r not a successor of %r
- invalid requirement: %s
- unexpected trailing data: %s
- path '%s' cannot be absolute
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/6d8b357f831f50db.
Report an issue: GitHub.