podman-container-tools/podman · error · Exception
'{matchobj[0]}' matches 'pod' in both left and right sides
Error message
'{matchobj[0]}' matches 'pod' in both left and right sides What it means
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.
Source
Thrown at hack/markdown-preprocess:256
Replace instances of '<<pod string|container string>>' with the
appropriate one based on whether this is a pod-related man page
or not.
"""
# Internal helper function: determines the desired half of the <a|b> string
def replwith(matchobj):
lhs, rhs = matchobj[0].split('|')
# Strip off '<<' and '>>'
lhs = lhs[2:]
rhs = rhs[:len(rhs)-2]
# Check both sides for 'pod' followed by (non-"m" or end-of-string).
# The non-m prevents us from triggering on 'podman', which could
# conceivably be present in both sides. And we check for 'pod',
# not 'container', because it's possible to have something like
# <<container in pod|container>>.
if re.match('.*pod([^m]|$)', lhs, re.IGNORECASE):
if re.match('.*pod([^m]|$)', rhs, re.IGNORECASE):
raise Exception(f"'{matchobj[0]}' matches 'pod' in both left and right sides")
# Only left-hand side has "pod"
if self.pod_or_container == 'pod':
return lhs
return rhs
# 'pod' not in lhs, must be in rhs
if not re.match('.*pod([^m]|$)', rhs, re.IGNORECASE):
raise Exception(f"'{matchobj[0]}' does not match 'pod' in either side")
if self.pod_or_container == 'pod':
return rhs
return lhs
return re.sub(r'<<[^\|>]*\|[^\|>]*>>', replwith, line)
def main():
"script entry point"
script_dir = os.path.abspath(os.path.dirname(__file__))View on GitHub (pinned to a2409076ef)
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
Example fix
# before <<create the pod|delete the pod>> # after <<create the pod|create the container>>
Defensive patterns
Strategy: validation
Validate before calling
# Lint <<a|b>> tokens: 'pod' (not inside 'podman') must appear in exactly one half
import re, pathlib, sys
pat = re.compile(r'<<[^|>]*\|[^|>]*>>')
pod = re.compile(r'.*pod([^m]|$)', re.IGNORECASE)
bad = []
for p in pathlib.Path('docs/source/markdown/options').glob('*.md'):
for line_no, line in enumerate(p.read_text().splitlines(), 1):
for tok in pat.findall(line):
lhs, rhs = tok[2:-2].split('|')
if pod.match(lhs) and pod.match(rhs):
bad.append(f'{p}:{line_no}: pod on both sides: {tok}')
if bad:
sys.exit('\n'.join(bad)) Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- '{matchobj[0]}' does not match 'pod' in either side
- undefined variable: {name}
- `else` without `if`
- multiple `else` in the same `if`
- `end` without `if`
AI-assisted analysis of podman-container-tools/podman@a2409076ef (2026-08-15).
Data as JSON: /api/errors/46c134a29ee26a18.
Report an issue: GitHub.