fxsjy/jieba · critical · ValueError
invalid POS dictionary entry in %s at Line %s: %s
Error message
invalid POS dictionary entry in %s at Line %s: %s
What it means
posseg's load_word_tag parses the POS dictionary expecting exactly 'word tag' separated by a single space per line (line.split(' ')). Any line that raises during strip/decode/split — wrong encoding, more than one space, or split not yielding 3 values — is reported as an invalid POS dictionary entry with file, line number, and content.
Source
Thrown at jieba/posseg/__init__.py:108
raise NotImplementedError
return getattr(self.tokenizer, name)
def initialize(self, dictionary=None):
self.tokenizer.initialize(dictionary)
self.load_word_tag(self.tokenizer.get_dict_file())
def load_word_tag(self, f):
self.word_tag_tab = {}
f_name = resolve_filename(f)
for lineno, line in enumerate(f, 1):
try:
line = line.strip().decode("utf-8")
if not line:
continue
word, _, tag = line.split(" ")
self.word_tag_tab[word] = tag
except Exception:
raise ValueError(
'invalid POS dictionary entry in %s at Line %s: %s' % (f_name, lineno, line))
f.close()
def makesure_userdict_loaded(self):
if self.tokenizer.user_word_tag_tab:
self.word_tag_tab.update(self.tokenizer.user_word_tag_tab)
self.tokenizer.user_word_tag_tab = {}
def __cut(self, sentence):
prob, pos_list = viterbi(
sentence, char_state_tab_P, start_P, trans_P, emit_P)
begin, nexti = 0, 0
for i, char in enumerate(sentence):
pos = pos_list[i][0]
if pos == 'B':
begin = i
elif pos == 'E':View on GitHub (pinned to 67fa2e36e7)
Solutions
- Fix the reported line: exactly 'word TAG', single space separator, UTF-8, no BOM
- Normalize the file programmatically: split on any whitespace and re-join with a single space
- Restore the default dict.txt.pos via pip install --force-reinstall jieba
- Never pass a plain frequency dict (word freq) to posseg.initialize — it must include POS tags
Example fix
# before
# posdict line: '北京 ns extra' -> ValueError
jieba.posseg.initialize('posdict.txt')
# after
with open('posdict.txt', encoding='utf-8') as f:
rows = [ln.split()[:2] for ln in f if ln.strip()]
with open('posdict_fixed.txt', 'w', encoding='utf-8') as f:
f.write('\n'.join('%s %s' % (w, t) for w, t in rows))
jieba.posseg.initialize('posdict_fixed.txt') Defensive patterns
Strategy: validation
Validate before calling
import re
def posdict_ok(path):
pat = re.compile(r'^\S+ [a-z]+\s*$', re.IGNORECASE)
with open(path, encoding='utf-8') as f:
for i, ln in enumerate(f, 1):
if ln.strip() and not pat.match(ln):
return False, i, ln
return True, None, None Try / catch
try:
jieba.posseg.initialize(p)
except ValueError as e:
# message contains file, line number, offending line
fix_pos_line(e); jieba.posseg.initialize(p) Prevention
- Generate POS dicts as 'word TAG' with exactly one space
- Never reuse plain frequency dicts for posseg
- Keep files UTF-8; validate in CI
When it happens
Trigger: Initializing jieba.posseg with a custom dictionary whose lines aren't 'word TAG' (single space), contain multiple spaces, are non-UTF-8, or where the default dict.txt.pos is corrupted. Triggered on first posseg call or posseg.initialize(dictionary).
Common situations: Custom dictionaries generated with tabs or multiple spaces; GBK-encoded POS dicts; tabs instead of spaces; corrupted default dict.txt.pos after a bad install; reusing a plain jieba dict (no tag column) as a POS dict.
Related errors
- invalid dictionary entry in %s at Line %s: %s
- jieba: the input parameter should be unicode.
- jieba: file does not exist: %s
- dictionary file %s must be utf-8
- jieba: parallel mode only supports posix system
AI-assisted analysis of fxsjy/jieba@67fa2e36e7 (2026-08-27).
Data as JSON: /api/errors/e4942f13ff58e0c2.
Report an issue: GitHub.