{"record":{"id":"46c134a29ee26a18","repo":"podman-container-tools/podman","slug":"matchobj-0-matches-pod-in-both-left-and-rig","errorCode":null,"errorMessage":"'{matchobj[0]}' matches 'pod' in both left and right sides","messagePattern":"'(.+?)' matches 'pod' in both left and right sides","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"hack/markdown-preprocess","lineNumber":256,"sourceCode":"        Replace instances of '<<pod string|container string>>' with the\n        appropriate one based on whether this is a pod-related man page\n        or not.\n        \"\"\"\n        # Internal helper function: determines the desired half of the <a|b> string\n        def replwith(matchobj):\n            lhs, rhs = matchobj[0].split('|')\n            # Strip off '<<' and '>>'\n            lhs = lhs[2:]\n            rhs = rhs[:len(rhs)-2]\n\n            # Check both sides for 'pod' followed by (non-\"m\" or end-of-string).\n            # The non-m prevents us from triggering on 'podman', which could\n            # conceivably be present in both sides. And we check for 'pod',\n            # not 'container', because it's possible to have something like\n            # <<container in pod|container>>.\n            if re.match('.*pod([^m]|$)', lhs, re.IGNORECASE):\n                if re.match('.*pod([^m]|$)', rhs, re.IGNORECASE):\n                    raise Exception(f\"'{matchobj[0]}' matches 'pod' in both left and right sides\")\n                # Only left-hand side has \"pod\"\n                if self.pod_or_container == 'pod':\n                    return lhs\n                return rhs\n\n            # 'pod' not in lhs, must be in rhs\n            if not re.match('.*pod([^m]|$)', rhs, re.IGNORECASE):\n                raise Exception(f\"'{matchobj[0]}' does not match 'pod' in either side\")\n            if self.pod_or_container == 'pod':\n                return rhs\n            return lhs\n\n        return re.sub(r'<<[^\\|>]*\\|[^\\|>]*>>', replwith, line)\n\n\ndef main():\n    \"script entry point\"\n    script_dir = os.path.abspath(os.path.dirname(__file__))","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/podman-container-tools/podman/blob/a2409076ef2fef60ad9ac046375dedc7d9410ef4/hack/markdown-preprocess#L238-L274","documentation":"Raised by the replwith() callback in Preprocessor.replace_type() while rewriting '<<lhs|rhs>>' tokens: the regex '.*pod([^m]|$)' (case-insensitive) matched the word 'pod' on BOTH sides of the '|', so the script cannot decide which side to keep. The ([^m]|$) guard exists so 'podman' does not count as 'pod'. replace_type runs on every line of every included option file (insert_file), so this fires during docs generation for any option file with an ambiguous pod|container token.","triggerScenarios":"An options/*.md line contains something like '<<create the pod|delete the pod>>' — 'pod' (word, not 'podman') appears in both halves. Note the regex is substring-based: any text ending in 'pod' or containing 'pod' followed by a non-'m' character (e.g. 'podman-pod', 'pods') matches.","commonSituations":"Writing option descriptions that mention pods on both the container and pod variants; reusing 'pod' as a suffix on both sides (e.g. '<<pod create|pod kill>>'); editing shared option files used by both podman-*-pod-* and other man pages.","solutions":["Reword so exactly one side contains 'pod' (as a word or suffix), e.g. '<<create the pod|create the container>>'","If both outputs are genuinely identical and mention pods, drop the <<a|b>> construct and write the literal text"],"exampleFix":"# before\n<<create the pod|delete the pod>>\n\n# after\n<<create the pod|create the container>>","handlingStrategy":"validation","validationCode":"# Lint <<a|b>> tokens: 'pod' (not inside 'podman') must appear in exactly one half\nimport re, pathlib, sys\npat = re.compile(r'<<[^|>]*\\|[^|>]*>>')\npod = re.compile(r'.*pod([^m]|$)', re.IGNORECASE)\nbad = []\nfor p in pathlib.Path('docs/source/markdown/options').glob('*.md'):\n    for line_no, line in enumerate(p.read_text().splitlines(), 1):\n        for tok in pat.findall(line):\n            lhs, rhs = tok[2:-2].split('|')\n            if pod.match(lhs) and pod.match(rhs):\n                bad.append(f'{p}:{line_no}: pod on both sides: {tok}')\nif bad:\n    sys.exit('\\n'.join(bad))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reserve the <<a|b>> construct strictly for pod-vs-container phrasing; one half must contain 'pod' (word or suffix, not the 'pod' in 'podman')","Run the token lint in CI — it checks both the both-sides and neither-side failure modes"],"tags":["markdown","docs","preprocessor","man-pages"],"backgroundTag":null,"analyzedSha":"a2409076ef2fef60ad9ac046375dedc7d9410ef4","analyzedAt":"2026-08-15T15:57:05.625Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}