Troubleshooting¶
The CLI exits with status 1 and prints nothing¶
The CLI catches every exception and calls sys.exit(1). Validation failures happen before any logging, so they leave no message. Check these causes in order:
-
The input file does not exist. The path is relative to the current directory.
-
A language code is invalid. Codes must be two lowercase ASCII letters.
EN,en-US,pt_BRanddeuall fail. -
The input is empty or contains only whitespace.
To see the actual exception, call the converter from Python, where it is not swallowed:
from pathlib import Path
from vexy_markliff import VexyMarkliff
text = Path("guide.md").read_text(encoding="utf-8")
VexyMarkliff().markdown_to_xliff(text, "en", "de")
The traceback names the exception (ValidationError, ConversionError) and its message, for example Invalid target language code: EN.
The CLI exits with status 1 and logs a parse error¶
Errors raised inside the conversion step are logged before the exit, for example:
Failed to parse XLIFF XML: Couldn't find end of Start Tag bad line 1, line 2, column 1 (<string>, line 2)
XLIFF to Markdown conversion failed: Invalid XLIFF XML: ...
The input for xliff2md or xliff2html is not well-formed XML. Check it with an XML validator or python -c "from lxml import etree; etree.parse('file.xlf')".
xliff2md writes an empty file¶
The command succeeded but found no units. The reader looks only for <trans-unit> elements in the namespace urn:oasis:names:tc:xliff:document:2.1. Files from other tools usually use the XLIFF 2.x structure (<unit>, <segment>) or the XLIFF 1.2 namespace (urn:oasis:names:tc:xliff:document:1.2), and both yield zero units.
Only files written by vexy-markliff itself are read correctly. See XLIFF output.
The translated text does not appear after converting back¶
xliff2md and xliff2html use the <source> text of each unit and ignore <target>. This is a limitation of version 1.3. To get the translations out, read the targets with the models:
from pathlib import Path
from vexy_markliff.models.xliff import XLIFFDocument
doc = XLIFFDocument.from_xml(Path("guide.de.xlf").read_text(encoding="utf-8"))
for unit in doc.files[0].units:
print(unit.id, unit.target or unit.source)
A sentence is split across several units¶
Inline markup splits text. Save **now** please becomes three units: Save, now, please. The extractor works on lxml text nodes and does not yet use inline codes (<mrk>, <ph>). The planned behaviour is described in HTML mapping rules.
Script, style or code text appears in the XLIFF¶
The extractor takes every text node, including <script>, <style>, <pre> and <code> content. Remove such content before conversion, or drop the matching units afterwards.
Headings, lists and links are lost on the way back¶
The reverse conversion writes one <p> per unit and has no record of the original element. Keep the original document; version 1.3 cannot rebuild it from the XLIFF.
The configuration file has no effect¶
ConversionConfig.load() reads source_language, target_language and split_sentences from YAML, but the CLI has no option to load it, and the converter does not read the values. Pass language codes as method arguments or CLI flags.
ConversionConfig.load() also returns the default configuration, without raising, when the file is missing or contains an invalid value. If your settings seem ignored when you use it directly, inspect the returned object:
from vexy_markliff import ConversionConfig
config = ConversionConfig.load("vexy-markliff.yaml")
print(config.source_language, config.target_language, config.split_sentences)
__version__ is unknown¶
vexy_markliff/__version__.py is generated by hatch-vcs when the package is built or installed. A bare source checkout on sys.path does not have it. Install the package (uv pip install -e .) to generate it.
The examples/ scripts fail with ModuleNotFoundError¶
The scripts in examples/ import modules such as vexy_markliff.core.element_classifier and vexy_markliff.core.format_style, which were removed when the code base was simplified. They do not run against version 1.3. Use the snippets in Quick start and Python API instead.