{"record":{"id":"a230a3b1d28a45c5","repo":"stanfordnlp/CoreNLP","slug":"caught-bad-number","errorCode":null,"errorMessage":"Caught bad number: ","messagePattern":"Caught bad number: ","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/edu/stanford/nlp/time/TimeExpressionExtractorImpl.java","lineNumber":194,"sourceCode":"    if (refDateStr != null) {\n      try {\n        // TODO: have more robust parsing of document date?  docDate may not have century....\n        // TODO: if docDate didn't change, we can cache the parsing of the docDate and not repeat it for every sentence\n        refDate = SUTime.parseDateTime(refDateStr,true);\n      } catch (Exception e) {\n        throw new RuntimeException(\"Could not parse date string: [\" + refDateStr + \"]\", e);\n      }\n    }\n    return extractTimeExpressions(annotation, refDate, timeIndex);\n  }\n\n  public List<TimeExpression> extractTimeExpressions(CoreMap annotation, SUTime.Time refDate, SUTime.TimeIndex timeIndex) {\n    if (!annotation.containsKey(CoreAnnotations.NumerizedTokensAnnotation.class)) {\n      try {\n        List<CoreMap> mergedNumbers = NumberNormalizer.findAndMergeNumbers(annotation);\n        annotation.set(CoreAnnotations.NumerizedTokensAnnotation.class, mergedNumbers);\n      } catch (NumberFormatException e) {\n        logger.warn(\"Caught bad number: \" + e.getMessage());\n        annotation.set(CoreAnnotations.NumerizedTokensAnnotation.class, new ArrayList<>());\n      }\n    }\n\n    List<? extends MatchedExpression> matchedExpressions = expressionExtractor.extractExpressions(annotation);\n    List<TimeExpression> timeExpressions = new ArrayList<>(matchedExpressions.size());\n    for (MatchedExpression expr : matchedExpressions) {\n      // Make sure we have the correct type (instead of just MatchedExpression)\n      //timeExpressions.add(TimeExpression.TimeExpressionConverter.apply(expr));\n\n      // TODO: Fix the extraction pipeline so it creates TimeExpression instead of MatchedExpressions\n      // For now, grab the time expression from the annotation (this is good, so we don't have duplicate copies)\n      TimeExpression annoTe = expr.getAnnotation().get( TimeExpression.Annotation.class );\n      if (annoTe != null) {\n        timeExpressions.add(annoTe);\n      }\n    }\n    // We cache the document date in the timeIndex","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/time/TimeExpressionExtractorImpl.java#L176-L212","documentation":"A logged warning in extractTimeExpressions: NumberNormalizer.findAndMergeNumbers threw a NumberFormatException while normalizing numeric tokens into NumerizedTokensAnnotation. The code logs 'Caught bad number: <message>' and sets an empty list so annotation can proceed without numbers. Text containing unparseable numeric expressions triggers it.","triggerScenarios":"Calling extractTimeExpressions (or running the 'sutime' annotator) on a CoreMap whose tokenized text contains number-like strings NumberNormalizer cannot parse (e.g. very long digit strings, mixed alphanumeric tokens like '3rd-and-4', locale-odd numbers).","commonSituations":"Noisy user text, OCR output, tweets with strings like '100000000000000000000x'; also occurs when custom tokenization splits numbers in ways NumberNormalizer does not expect.","solutions":["Inspect the logged message for the offending token and normalize/clean such numbers before annotation","Ensure standard tokenization options are used (sutime expects CoreNLP tokenizer output)","Upgrade CoreNLP; NumberNormalizer robustness has improved across versions","Accept the degradation: the code already continues with an empty numbers list; only time expressions depending on those numbers are lost"],"exampleFix":"// before\n// annotating raw noisy text directly\nCoreDocument doc = new CoreDocument(\"raw OCR text 0000000000000000000.5.5\");\npipeline.annotate(doc);\n// after\nString cleaned = raw.replaceAll(\"(?<=\\\\d)\\\\.(?=\\\\.|\\\\d*\\\\.\\\\d*\\\\.)\", \"\"); // drop malformed number runs\nCoreDocument doc = new CoreDocument(cleaned);\npipeline.annotate(doc);","handlingStrategy":"validation","validationCode":"// pre-clean number-like tokens that break NumberNormalizer\nString cleaned = text.replaceAll(\"\\\\b\\\\d{15,}\\\\b\", \"\")           // absurdly long digit strings\n                     .replaceAll(\"(?<=[0-9])[._](?=[._])\", \"\");   // malformed decimal runs","typeGuard":null,"tryCatchPattern":"try {\n  pipeline.annotate(doc);\n} catch (Exception e) {\n  log.warn(\"Annotation pipeline issue\", e); // NumberFormatException itself is caught by CoreNLP\n}","preventionTips":["Feed CoreNLP its own tokenizer output instead of pre-split strings","Clean OCR/social-media noise before annotation","Check the 'Caught bad number' logs to build a cleaning allowlist for your domain"],"tags":["java","nlp","number-normalization","sutime"],"backgroundTag":"invalid-argument-format","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"}