{"record":{"id":"7781c56a119fda7c","repo":"hankcs/HanLP","slug":"eval-pl-exited-with-error-code-exitcode-and-erro","errorCode":null,"errorMessage":"eval.pl exited with error code {exitcode} and error message {err} and output {out}.","messagePattern":"eval\\.pl exited with error code (.+?) and error message (.+?) and output (.+?)\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"hanlp/metrics/parsing/conllx_eval.py","lineNumber":33,"sourceCode":"    Args:\n      gold_file(str): The gold conllx file\n      pred_file(str): The pred conllx file\n\n    Returns:\n\n    \n    \"\"\"\n    gold_file = get_resource(gold_file)\n    fixed_pred_file = tempfile.NamedTemporaryFile().name\n    copy_cols(gold_file, pred_file, fixed_pred_file, keep_comments=False)\n    if gold_file.endswith('.conllu'):\n        fixed_gold_file = tempfile.NamedTemporaryFile().name\n        copy_cols(gold_file, gold_file, fixed_gold_file, keep_comments=False)\n        gold_file = fixed_gold_file\n\n    exitcode, out, err = get_exitcode_stdout_stderr(f'perl {CONLLX_EVAL} -q -b -g {gold_file} -s {fixed_pred_file}')\n    if exitcode:\n        raise RuntimeError(f'eval.pl exited with error code {exitcode} and error message {err} and output {out}.')\n    lines = out.split('\\n')[-4:]\n    las = int(lines[0].split()[3]) / int(lines[0].split()[5])\n    uas = int(lines[1].split()[3]) / int(lines[1].split()[5])\n    return uas, las\n\n\ndef copy_cols(gold_file, pred_file, copied_pred_file, keep_comments=True):\n    \"\"\"Copy the first 6 columns from gold file to pred file\n\n    Args:\n      gold_file: \n      pred_file: \n      copied_pred_file: \n      keep_comments:  (Default value = True)\n\n    Returns:\n\n    ","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/hankcs/HanLP/blob/ddb1299bddff079e447af52ec12549c50636bfa8/hanlp/metrics/parsing/conllx_eval.py#L15-L51","documentation":"The dependency-parsing evaluator shells out to the external Perl script eval.pl (CONLLX_EVAL) to compute UAS/LAS. If the Perl process exits with a nonzero status, HanLP re-raises its stderr/stdout as a RuntimeError.","triggerScenarios":"Calling conllx_eval.evaluate(gold_file, pred_file) when perl is missing/broken, eval.pl is not found at the expected path, or the gold/pred CoNLL-X files are malformed enough that eval.pl itself fails.","commonSituations":"Environments without perl installed (Windows, slim Docker images); running from a directory where the bundled eval.pl cannot be resolved; corrupted or empty prediction files produced by a failed parse step.","solutions":["Ensure perl is installed and on PATH (perl -v).","Inspect the reported stderr message — it usually states the real cause (e.g. 'No such file or directory' for missing eval.pl or an unreadable input file).","Validate that both gold and prediction files exist and are well-formed CoNLL-X (tab-separated, sentences separated by blank lines) before evaluating.","If you cannot install perl, use a pure-Python UAS/LAS implementation instead of this wrapper."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import shutil\nassert shutil.which('perl'), 'perl is required for conllx eval'","typeGuard":null,"tryCatchPattern":"try:\n    uas, las = evaluate(gold, pred)\nexcept RuntimeError as e:\n    log.error('eval.pl failed: %s', e)\n    raise","preventionTips":["Pre-check shutil.which('perl') before evaluation.","Validate CoNLL files (column counts, blank-line separators) with a small parser before eval."],"tags":["subprocess","perl","dependency-parsing","evaluation"],"backgroundTag":"subprocess-exit-nonzero","analyzedSha":"ddb1299bddff079e447af52ec12549c50636bfa8","analyzedAt":"2026-08-27T03:36:54.287Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}