{"record":{"id":"96bfa350afc41924","repo":"podman-container-tools/podman","slug":"multiple-else-in-the-same-if","errorCode":null,"errorMessage":"multiple `else` in the same `if`","messagePattern":"multiple `else` in the same `if`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"hack/markdown-preprocess","lineNumber":87,"sourceCode":"            # write literal up to token\n            literal = text[pos:m.start()]\n            if is_active():\n                out.append(literal)\n            pos = m.end()\n\n            inner = m.group(1).strip()\n\n            # control blocks\n            if inner.startswith(\"if \") and len(inner[3:].strip().split(\" \")) in [1, 2]:\n                cond = inner[3:].strip()\n                stack.append({\"active\": is_active() and truthy(cond), \"seen_else\": False})\n                continue\n            if inner == \"else\":\n                if not stack:\n                    raise ValueError(\"`else` without `if`\")\n                frame = stack[-1]\n                if frame[\"seen_else\"]:\n                    raise ValueError(\"multiple `else` in the same `if`\")\n                frame[\"seen_else\"] = True\n                parent_active = all(f[\"active\"] for f in stack[:-1])\n                frame[\"active\"] = parent_active and not frame[\"active\"]\n                continue\n            if inner == \"endif\":\n                if not stack:\n                    raise ValueError(\"`end` without `if`\")\n                stack.pop()\n                continue\n\n            # inline \"X if cond else Y\" ---\n            if \" if \" in inner and \" else \" in inner:\n                try:\n                    # split by \" if \" then \" else \"\n                    then_part, rest = inner.split(\" if \", 1)\n                    cond, else_part = rest.split(\" else \", 1)\n                    cond = cond.strip()\n                    chosen = then_part if truthy(cond) else else_part","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/podman-container-tools/podman/blob/a2409076ef2fef60ad9ac046375dedc7d9410ef4/hack/markdown-preprocess#L69-L105","documentation":"Raised when render() sees a second '<< else >>' for the same '<< if >>' frame (frame['seen_else'] is already True). Each if-frame supports exactly one else branch; there is no elseif/elif construct in this mini-language. Usually a copy-paste of a two-branch block that already contained an else.","triggerScenarios":"An options/*.md file contains '<< if VAR >>A<< else >>B<< else >>C<< endif >>', or text like 'if X ... else ... else if Y' translated literally into tokens (the second else belongs to the same frame).","commonSituations":"Translating shell/Python if/elif/else prose into man-page conditionals; duplicating a branch block and forgetting to remove the embedded else; attempting three-way branching in a template that only supports two.","solutions":["Rewrite as two blocks: '<< if VAR >>A<< endif >>' plus '<< if not VAR >>B or C<< endif >>'","Or move the third case into an inline token: '<< \"B\" if not VAR else \"A\" >>'","Delete whichever else branch is obsolete"],"exampleFix":"# before\n<< if is_quadlet >>A<< else >>B<< else >>C<< endif >>\n\n# after\n<< if is_quadlet >>A<< else >>B<< endif >>\n<< if not is_quadlet >>C<< endif >>","handlingStrategy":"validation","validationCode":"import re, pathlib\ndef lint(text, name):\n    stack = []\n    for m in re.finditer(r'<<(.*?)>>', text, re.DOTALL):\n        inner = m.group(1).strip()\n        if inner.startswith('if ') and len(inner[3:].split()) in (1, 2):\n            stack.append(False)\n        elif inner == 'else':\n            assert stack, f'{name}: `else` without `if`'\n            assert not stack[-1], f'{name}: multiple `else` near offset {m.start()}'\n            stack[-1] = True\n        elif inner == 'endif':\n            assert stack, f'{name}: `end` without `if`'\n            stack.pop()\n    assert not stack, f'{name}: unclosed `if` block(s)'\nfor p in pathlib.Path('docs/source/markdown/options').glob('*.md'):\n    lint(p.read_text(), str(p))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember the template has exactly two branches per if — plan A/B wording before writing","For three-way content use two ifs ('if' and 'if not') instead of a second else","Run the stack lint in CI; it detects else-without-if, duplicate else, stray endif, and unclosed if in one pass"],"tags":["markdown","docs","preprocessor","conditionals"],"backgroundTag":null,"analyzedSha":"a2409076ef2fef60ad9ac046375dedc7d9410ef4","analyzedAt":"2026-08-15T15:57:05.625Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}