hankcs/HanLP · error · ValueError
Expect X to be 2 or 3 elements but got {repr(X)}
Error message
Expect X to be 2 or 3 elements but got {repr(X)} What it means
X_to_inputs expects the feature batch X to be a 2-tuple (forms, cposes) or 3-tuple (forms, cposes, mask), matching the TF parsing model's output arrangement. Any other length triggers this ValueError.
Source
Thrown at hanlp/transform/conll_tf.py:55
def use_pos(self):
return self.config.get('use_pos', True)
def x_to_idx(self, x) -> Union[tf.Tensor, Tuple]:
form, cpos = x
return self.form_vocab.token_to_idx_table.lookup(form), self.cpos_vocab.token_to_idx_table.lookup(cpos)
def y_to_idx(self, y):
head, rel = y
return head, self.rel_vocab.token_to_idx_table.lookup(rel)
def X_to_inputs(self, X: Union[tf.Tensor, Tuple[tf.Tensor]]) -> Iterable:
if len(X) == 2:
form_batch, cposes_batch = X
mask = tf.not_equal(form_batch, 0)
elif len(X) == 3:
form_batch, cposes_batch, mask = X
else:
raise ValueError(f'Expect X to be 2 or 3 elements but got {repr(X)}')
sents = []
for form_sent, cposes_sent, length in zip(form_batch, cposes_batch,
tf.math.count_nonzero(mask, axis=-1)):
forms = tolist(form_sent)[1:length + 1]
cposes = tolist(cposes_sent)[1:length + 1]
sents.append([(self.form_vocab.idx_to_token[f],
self.cpos_vocab.idx_to_token[c]) for f, c in zip(forms, cposes)])
return sents
def lock_vocabs(self):
super().lock_vocabs()
self.puncts = tf.constant([i for s, i in self.form_vocab.token_to_idx.items()
if ispunct(s)], dtype=tf.int64)
def file_to_inputs(self, filepath: str, gold=True):
assert gold, 'only support gold file for now'View on GitHub (pinned to ddb1299bdd)
Solutions
- Pack X as exactly (form_batch, cposes_batch) or (form_batch, cposes_batch, mask).
- Check the upstream component that produced X — a mismatch usually means you are feeding data from the wrong model/stage.
- Verify no extra element (e.g. lemma features) was appended to X.
Example fix
# before inputs = transform.X_to_inputs([forms, cposes, mask, lemmas]) # after inputs = transform.X_to_inputs([forms, cposes, mask])
Defensive patterns
Strategy: type-guard
Validate before calling
assert isinstance(X, (list, tuple)) and len(X) in (2, 3), 'X must be (forms, cposes[, mask])'
Type guard
def is_valid_X(X):
return isinstance(X, (list, tuple)) and len(X) in (2, 3) and hasattr(X[0], 'shape') Prevention
- Construct X right where the model outputs are unpacked, so element count matches by construction.
- Pin the model/transform pair from the same HanLP version.
When it happens
Trigger: Calling XY_to_inputs_outputs/X_to_inputs with an X that is a list/tuple of length other than 2 or 3, e.g. feeding raw tensors, a single stacked tensor, or a 4-element tuple with extra features.
Common situations: Changing the model's feature layout without updating the transform; passing numpy arrays from a different pipeline; hand-crafting inputs for the TF parser.
Related errors
- The last dimension of the inputs to `CRF` should be defined.
- transformers has its own tagger, not need to convert idx for
- transformers has its own tagger, not need to convert idx for
- the first two dimensions of emissions and tags must match, g
- The last dimension of the input shape must be equal to outpu
AI-assisted analysis of hankcs/HanLP@ddb1299bdd (2026-08-27).
Data as JSON: /api/errors/ec58b9a566c5f116.
Report an issue: GitHub.