stanfordnlp/CoreNLP · error · RuntimeException
format error unexpected featureFactory line:
Error message
format error unexpected featureFactory line:
What it means
Thrown when the featureFactory line of the text-serialized model does not match the expected '<featureFactory> name </featureFactory>' layout: it must contain at least the open/close markers and the class name between them. The message appends the offending line.
Solutions
- Ensure the line is exactly '<featureFactory> edu.stanford.nlp...FeatureFactory </featureFactory>' on one line
- Reformat the line back to a single line if an editor wrapped it
- Regenerate the model with CRFClassifier.writeModel from the same CoreNLP version
- Confirm the FeatureFactory class name is fully qualified (the loader also calls Class.forName on it)
Example fix
// before: line wrapped/reformatted in the model file // <featureFactory> // edu.stanford.nlp.wordseg.ChineseSegmenterFeatureFactory // </featureFactory> // after: single line with markers // <featureFactory> edu.stanford.nlp.wordseg.ChineseSegmenterFeatureFactory </featureFactory>
Defensive patterns
Strategy: validation
Validate before calling
// Validate the featureFactory line format before loading
static boolean featureFactoryLineValid(String line) {
if (line == null) return false;
String[] toks = line.split(" ");
return toks.length >= 2 && toks[0].equals("<featureFactory>") && toks[toks.length - 1].equals("</featureFactory>");
} Type guard
static boolean isFeatureFactoryLine(String line) {
String[] toks = line == null ? new String[0] : line.split(" ");
return toks.length >= 2 && "<featureFactory>".equals(toks[0]) && "</featureFactory>".equals(toks[toks.length - 1]);
} Try / catch
try {
CRFClassifier<CoreLabel> model = CRFClassifier.getClassifier(modelPath);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("format error unexpected featureFactory line:")) {
throw new IllegalStateException("featureFactory line malformed (check it is one unwrapped line with both markers).", e);
}
throw e;
} Prevention
- Keep the featureFactory line on a single line — disable editor auto-wrap for model files
- Use fully-qualified FeatureFactory class names so Class.forName resolves
- Regenerate models rather than editing the featureFactory section by hand
- Avoid reformatting/whitespace normalization on serialized models
When it happens
Trigger: CRFClassifier.getClassifier on a model whose featureFactory line lacks '<featureFactory>'/'</featureFactory>' markers, has fewer than 2 space-separated tokens, or was wrapped/reformatted onto multiple lines.
Common situations: Text editors or formatters reflowed the long featureFactory line; custom models whose writer used a different marker format; edits or corruption in the flags/featureFactory region.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- format error in embeddings
- Error loading classifier from
- Unexpected number of field , expected >= for line (,):
- First line of input file should be header definition
- weights format error
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/a3aa77213c64a942.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/ie/crf/CRFClassifier.java:2234
count = 0;
while (count < embeddingSize) {
line = br.readLine().trim();
toks = line.split("\\t");
String word = toks[0];
double[] arr = ArrayUtils.toDoubleArray(toks[1].split(" "));
embeddings.put(word, arr);
count++;
}
}
// <featureFactory>
// edu.stanford.nlp.wordseg.Gale2007ChineseSegmenterFeatureFactory
// </featureFactory>
line = br.readLine();
String[] featureFactoryName = line.split(" ");
if (featureFactoryName.length < 2 || !featureFactoryName[0].equals("<featureFactory>") || !featureFactoryName[featureFactoryName.length - 1].equals("</featureFactory>")) {
throw new RuntimeException("format error unexpected featureFactory line: " + line);
}
featureFactories = Generics.newArrayList();
for (int ff = 1; ff < featureFactoryName.length - 1; ++ff) {
FeatureFactory<IN> featureFactory = (FeatureFactory<IN>) Class.forName(featureFactoryName[1]).newInstance();
featureFactory.init(flags);
featureFactories.add(featureFactory);
}
reinit();
// <windowSize> 2 </windowSize>
line = br.readLine();
String[] windowSizeName = line.split(" ");
if (!windowSizeName[0].equals("<windowSize>") || !windowSizeName[2].equals("</windowSize>")) {
throw new RuntimeException("format error");
}
windowSize = Integer.parseInt(windowSizeName[1]);View on GitHub (pinned to 1b7edd19c4)