{"record":{"id":"b25cb2bec20793b7","repo":"PaddlePaddle/PaddleOCR","slug":"source-ref-must-be-a-non-empty-ref-without-whitesp","errorCode":null,"errorMessage":"source_ref must be a non-empty ref without whitespace","messagePattern":"source_ref must be a non-empty ref without whitespace","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"tools/resolve_doc_github_refs.py","lineNumber":15,"sourceCode":"#!/usr/bin/env python3\nimport argparse\nfrom pathlib import Path\n\n\nTEXT_SUFFIXES = {\".md\", \".yml\", \".yaml\"}\n\n\ndef resolve_placeholders(root, placeholder, source_ref):\n    if (\n        not source_ref\n        or source_ref.strip() != source_ref\n        or any(c.isspace() for c in source_ref)\n    ):\n        raise ValueError(\"source_ref must be a non-empty ref without whitespace\")\n\n    root = Path(root)\n    changed = []\n    for path in sorted(root.rglob(\"*\")):\n        if not path.is_file() or path.suffix not in TEXT_SUFFIXES:\n            continue\n        content = path.read_text(encoding=\"utf-8\")\n        if placeholder not in content:\n            continue\n        path.write_text(content.replace(placeholder, source_ref), encoding=\"utf-8\")\n        changed.append(path)\n    return changed\n\n\ndef main(argv=None):\n    parser = argparse.ArgumentParser(\n        description=\"Resolve docs GitHub source-ref placeholders before building docs.\"\n    )","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/tools/resolve_doc_github_refs.py#L1-L33","documentation":"tools/resolve_doc_github_refs.py is a docs-release helper that rewrites a placeholder string across all .md/.yml/.yaml files under a root. Before touching anything it validates source_ref: it must be non-empty, must not have leading/trailing whitespace, and must contain no whitespace anywhere. This ValueError prevents substituting malformed refs (e.g. 'main ' or 'release 2.9') into hundreds of documentation files, which would be tedious to revert.","triggerScenarios":"Running the script with --source-ref containing a space, tab, newline, or surrounding whitespace: python tools/resolve_doc_github_refs.py --source-ref 'main ' or '--source-ref v2.9 rc'.","commonSituations":"Shell quoting accidents letting extra words into the argument; copy-pasting a ref with a trailing newline; CI passing an unset/whitespace variable as the ref.","solutions":["Pass a clean single token: --source-ref v2.9.0 or --source-ref main","Quote the shell variable and strip it first: --source-ref \"${REF// /}\" or REF=$(echo \"$REF\" | tr -d '[:space:]')","Validate in CI before invoking: [ -n \"$REF\" ] && [[ \"$REF\" != *[' \t']* ]] || exit 1"],"exampleFix":"# before\npython tools/resolve_doc_github_refs.py --root docs --placeholder '@REF@' --source-ref \"main \"\n\n# after\npython tools/resolve_doc_github_refs.py --root docs --placeholder '@REF@' --source-ref main","handlingStrategy":"validation","validationCode":"assert source_ref and source_ref == source_ref.strip() and not any(c.isspace() for c in source_ref), \\\n    f'source_ref must be a single token without whitespace, got {source_ref!r}'","typeGuard":"def is_clean_ref(ref: str) -> bool:\n    return bool(ref) and ref.strip() == ref and not any(c.isspace() for c in ref)","tryCatchPattern":"try:\n    resolve_placeholders(root, placeholder, source_ref)\nexcept ValueError as e:\n    if 'source_ref' in str(e):\n        raise SystemExit(f'invalid --source-ref {source_ref!r}: pass a single git ref like v2.9.0')\n    raise","preventionTips":["Strip and validate CI-provided variables before passing them to docs scripts","Quote shell arguments and test scripts with refs containing spaces to catch quoting bugs early"],"tags":["docs-tooling","cli-arguments","validation","whitespace"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}