{"record":{"id":"d160bd85ca5fbed2","repo":"stanfordnlp/CoreNLP","slug":"addfeature-was-called-with-a-features-object-that","errorCode":null,"errorMessage":"addFeature was called with a features object that is neither a counter nor a collection!","messagePattern":"addFeature was called with a features object that is neither a counter nor a collection!","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/classify/ColumnDataClassifier.java","lineNumber":951,"sourceCode":"      double sqrt = Math.sqrt(value);\n      addFeature(featuresC, \"Sqrt\", sqrt);\n    } else {\n      addFeature(featuresC, Flags.realValuedFeaturePrefix, value);\n    }\n  }\n\n  /**\n   * This method takes care of adding features to the collection-ish object features via\n   * instanceof checks.  Features must be a type of collection or a counter, and value is used\n   * iff it is a counter\n   */\n  private static <F> void addFeature(Object features, F newFeature, double value) {\n    if (features instanceof Counter<?>) {\n      ErasureUtils.<Counter<F>>uncheckedCast(features).setCount(newFeature, value);\n    } else if(features instanceof Collection<?>) {\n      ErasureUtils.<Collection<F>>uncheckedCast(features).add(newFeature);\n    } else {\n      throw new RuntimeException(\"addFeature was called with a features object that is neither a counter nor a collection!\");\n    }\n  }\n\n  /**\n   * Extracts all the features from a certain input column.\n   *\n   * @param cWord The String to extract data from\n   * @param flags Flags specifying which features to extract\n   * @param featuresC Some kind of Collection or Counter to put features into\n   * @param goldAns The goldAnswer for this whole datum or emptyString if none.\n   *                    This is used only for filling in the binned lengths histogram counters\n   */\n  private void makeDatum(String cWord, Flags flags, Object featuresC, String goldAns) {\n\n    //logger.info(\"Making features for \" + cWord + \" flags \" + flags);\n    if (flags == null) {\n      // no features for this column\n      return;","sourceCodeStart":933,"sourceCodeEnd":969,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/classify/ColumnDataClassifier.java#L933-L969","documentation":"The private static helper addFeature expects the features accumulator to be either a Counter<F> (setCount with weight) or a Collection<F> (add). Any other object type is a programming invariant violation, thrown as RuntimeException. This is an internal-type contract inside ColumnDataClassifier's feature extraction.","triggerScenarios":"Internal feature-extraction code paths in ColumnDataClassifier construction that pass a features object created as neither Counter nor Collection (e.g. after refactoring the accumulator type); not normally triggerable from public API misuse.","commonSituations":"Subclassing/modifying ColumnDataClassifier and passing a Map or List-of-tuples as features; version drift where custom column classifiers return a non-standard container from their feature factory.","solutions":["Ensure the features accumulator is created as a ClassicCounter<F> (for weighted features) or ArrayList<F>/Collection (for binary features)","If you modified the code, restore the standard Counter/Collection container types in the feature extraction methods","Cast or wrap custom containers into a Counter/Collection before calling addFeature"],"exampleFix":"// before\nMap<String,Double> features = new HashMap<>();\naddFeature(features, feat, value);\n// after\nCounter<String> features = new ClassicCounter<>();\naddFeature(features, feat, value);","handlingStrategy":"type-guard","validationCode":"if (!(features instanceof Counter) && !(features instanceof Collection)) throw new IllegalArgumentException(\"features must be Counter or Collection\");","typeGuard":"static boolean isFeatureContainer(Object o) { return o instanceof Counter<?> || o instanceof Collection<?>; }","tryCatchPattern":"try { extractFeatures(...); } catch (RuntimeException e) { if (e.getMessage().contains(\"neither a counter nor a collection\")) { log.error(\"Feature accumulator misconfigured\", e); } else throw e; }","preventionTips":["Always accumulate features in ClassicCounter or a List/Collection","After refactoring feature extraction, keep the accumulator types aligned with addFeature","Add an assertion on the accumulator type before extraction loops"],"tags":["java","column-data-classifier","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}