Skip to content

A secondary with zero informative levels makes the entire XFORM score Inf, and MaximizeParsimony then aborts with missing value where TRUE/FALSE needed. #12

Description

@ms609

Severity: P1 · Area: 10 (HSJ/XFORM kernels)

Location: R/recode_hierarchy.R:106-109 (secNStates[s] == 0), :193-197 (-2 encoding); src/ts_rcpp.cpp:1936; abort at R/MaximizeParsimony.R:1717

secNStates[s] == 0 makes nPresent = prod(...) zero and nStates 1; every present-primary tip then encodes as the -2 sentinel, and src/ts_rcpp.cpp:1936 loops for (s = 1; s < ns) with ns == 1, admitting no state -- so all tip costs are INF and sankoff_score returns Inf. Verified REAL, and the reachability route (the load-bearing part) holds (opus verifier, build at bbab0f7c): a full 5-taxon dataset validates cleanly (n_states = 3), and then TreeLength(<4-tip tree>, ds, hierarchy = h, inapplicable = "xform") returns Inf silently, with no warning, while inapplicable = "hsj" returns a finite 4.5. ValidateHierarchy runs before both subsetting sites (R/MaximizeParsimony.R:1361 vs the taxon-drop at :1428; R/tree_length.R:276 vs the dataset[TipLabels(tree)] subset at :302), so it cannot see the degenerate block. .Recompress = MatrixToPhyDat(PhyDatToMatrix()) preserves the column count, so it is the taxon subset alone that does it -- i.e. valid user input reaching a degenerate state through a documented code path, not hand-crafted malformed input. Consequence corrected during verification, and the correction matters: MaximizeParsimony does not silently return the start tree with score = Inf as first claimed -- it aborts at R/MaximizeParsimony.R:1717 with Error in if (diff(range(canonicalScores)) > sqrt(.Machine$double.eps))): missing value where TRUE/FALSE needed, because diff(range(c(Inf, Inf))) is NaN. A louder symptom than claimed, but a worse one for the user, and it points at a second defect worth fixing in the same patch: :1717 will NaN for any all-Inf pool, whatever produced it. Cross-ref T-393 (shared root line) and T-379 (the other -2-sentinel defect, which under-counts by discarding known secondaries -- distinct failure, same sentinel).


Migrated 2026-08-04 from dev/red-team/findings.md; pre-tracker ID T-394. References to T-394 in source comments, dev/red-team/log.md, commit messages and PR bodies mean this issue — see dev/red-team/migration-map.tsv. Cross-repo references use the fully-qualified form agent-issues/TreeSearch#<n>; a bare #n means this repo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:10Red-team focus area 10in-progressBeing fixed; claiming comment names the branchred-teamFiled by the /red-team rotationsev:highP1: wrong user-visible result / crash

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions