{"record":{"id":"51f4a8fe85b7d414","repo":"stanfordnlp/CoreNLP","slug":"getpcfgscore-called-before-a-sentence-has-been-par","errorCode":null,"errorMessage":"getPCFGScore called before a sentence has been parsed","messagePattern":"getPCFGScore called before a sentence has been parsed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/parser/metrics/ExternalParserQuery.java","lineNumber":45,"sourceCode":"    this.originalSentence = sentence;\n    this.results = results;\n    this.success = (results != null);\n  }\n\n  @Override\n  public boolean parse(List<? extends HasWord> sentence) {\n    throw new UnsupportedOperationException();\n  }\n\n  @Override\n  public boolean parseAndReport(List<? extends HasWord> sentence, PrintWriter pwErr) {\n    return parse(sentence);\n  }\n\n  @Override\n  public double getPCFGScore() {\n    if (results == null) {\n      throw new IllegalStateException(\"getPCFGScore called before a sentence has been parsed\");\n    }\n    return results.get(0).score();\n  }\n\n  @Override\n  public Tree getBestParse() {\n    if (results == null) {\n      throw new IllegalStateException(\"getPCFGScore called before a sentence has been parsed\");\n    }\n    return results.get(0).object();\n  }\n\n  @Override\n  public List<ScoredObject<Tree>> getKBestParses(int k) {\n    if (results == null) {\n      throw new IllegalStateException(\"getPCFGScore called before a sentence has been parsed\");\n    }\n    if (results.size() > k) {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/parser/metrics/ExternalParserQuery.java#L27-L63","documentation":"ExternalParserQuery.getPCFGScore returns the score of the first stored parse result, but only after a parse has run; if 'results' is still null it throws IllegalStateException('getPCFGScore called before a sentence has been parsed'). It enforces the API contract: parse before querying scores.","triggerScenarios":"Calling getPCFGScore() on a freshly created ExternalParserQuery (or after a query on which parse() was never invoked) — commonly via getBestScore() which delegates to it.","commonSituations":"Code that inspects query results without checking whether parse() was called or succeeded, lifecycle bugs where the query object is queried before use, or exception paths that skipped the parse step.","solutions":["Call parse(sentence) (or parseAndScore) on the ParserQuery before reading getPCFGScore().","Guard the call: track whether a parse was performed for this query instance.","Wrap in try-catch for IllegalStateException and return a sentinel/throw a clearer domain error.","Create a new ParserQuery per sentence instead of sharing/querying stale instances."],"exampleFix":"// before\ndouble score = parserQuery.getPCFGScore();\n// after\nif (parserQuery.parse(sentence)) {\n  double score = parserQuery.getPCFGScore();\n}","handlingStrategy":"validation","validationCode":"boolean parsed = parserQuery.parse(sentence);\nif (!parsed) throw new IllegalStateException(\"parse() must be called (and succeed) before getPCFGScore()\");","typeGuard":null,"tryCatchPattern":"try {\n  double s = query.getPCFGScore();\n} catch (IllegalStateException e) {\n  // query never parsed; run parse first or return sentinel\n}","preventionTips":["Enforce call order: parse() before any score/tree accessor.","Use one ParserQuery per sentence.","Check parse()'s return value instead of assuming success.","Initialize query state centrally in a helper that always parses first."],"tags":["parser-query","illegal-state","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}