Skip to content

fix(Descriptions): keep Available exhaustive, let the hint carry its list (#557) - #558

Merged
ocots merged 1 commit into
mainfrom
fix/issue-557-available-hint
Sep 2, 2026
Merged

ocots merged 1 commit into
mainfrom
fix/issue-557-available-hint

Conversation

@ocots

@ocots ocots commented Sep 2, 2026

Copy link
Copy Markdown
Member

Closes #557, a follow-up to #553 (fixed by #556, released in v0.30.3-beta).

The problem

#556 routed the similarity-filtered matches into candidates. Exceptions/display.jl:157-159 labels that field Available, so the two message fields effectively swapped content:

│  Requested   (:adnlp, :gpu)
│  Available   (:collocation, :exa, :madnlp, :gpu)      ← 5 of 12, nothing says so
│              (:collocation, :exa, :madncl, :gpu)
│              (:collocation, :adnlp, :uno, :cpu)
│              (:collocation, :adnlp, :madnlp, :cpu)
│              (:collocation, :adnlp, :madncl, :cpu)
│
│  Hint        Try one of the closest matches:            ← nothing follows
└─

A reader asking "what can I call?" is given a filtered subset under a label that claims completeness, and the hint announces a list it never prints — the matches are on screen, under the wrong heading.

And #553's own truncation marker turned out to be unreachable. It is built from all_candidates, which was discarded whenever similar_descs was non-empty; _find_similar_descriptions returns empty only when the request shares no symbol with any description (_compute_similarity is a Jaccard index, filtered on > 0.0). So the marker could only render for a catalog above max_show and a wholly unknown request — never in the scenario #553 was filed about.

The fix — two lines, complete.jl only

_print_pipe_field already splits a String value on newlines and keeps the prefix and indentation (display.jl:283-291), so a multi-line hint renders correctly with no display change:

-            "Try one of the closest matches:"
+            string("Try one of the closest matches:\n", join(similar_descs, "\n"))
...
-                candidates=isempty(similar_descs) ? all_candidates : similar_descs,
+                candidates=all_candidates,

Each field goes back to its own job: candidates describes the catalog (exhaustive, or max_show plus the marker) on every path, and the hint carries its own list.

│  Available   (:collocation, :adnlp, :ipopt, :cpu)
│              … the other ten …
│              (:collocation, :exa, :madnlp, :gpu)
│              (:collocation, :exa, :madncl, :gpu)
│
│  Hint        Try one of the closest matches:
│              (:collocation, :exa, :madnlp, :gpu)
│              (:collocation, :exa, :madncl, :gpu)
│              (:collocation, :adnlp, :uno, :cpu)

Tests

A new issue 557 testset, five parts:

  1. The branch AmbiguousDescription: candidate list silently truncated at 10, and the "closest matches" hint is empty #553 could not reach — a catalog above max_show with similar matches: candidates must still be the catalog and still end on … and N more. This is the assertion that pins the second-order bug.
  2. Small catalog: candidates exhaustive (12 of 12), including the entries that do not resemble the request — that is what Available means.
  3. The hint is self-contained: header line, then one line per closest match.
  4. End to end: sprint(showerror, e) shows the matches after the Hint label, not only in the struct.
  5. The no-similarity path is untouched: single-sentence hint, catalog intact.

The #553 testset asserted the behaviour this PR fixes

Test.@test Set(err.candidates) == Set(["(:gpu, :exact)", "(:gpu, :krylov)"])

— so it is corrected here, with the closest-matches assertion moved to suggestion where it belongs. One nearby test ("description not found with similar suggestions") was checking the closest matches through candidates for the same reason; it now checks suggestion and asserts the catalog stays whole.

Verified the new tests bite: with the source change stashed, suite/descriptions/test_complete.jl fails at lines 212, 213 and 265; with it applied, suite/descriptions is 284/284 and the full suite is 121095/121095.

Verified downstream

Pkg.develop-ed this branch into OptimalControl.jl's documentation environment and re-ran the case that produced the report — solve(ocp, :adnlp, :gpu) on the 12-method registry — confirming both fields now read correctly on the page that publishes this message (solve/gpu.md, control-toolbox/OptimalControl.jl#941).

Also in this PR

  • 0.30.3-beta0.30.4-beta, CHANGELOG entry, and two BREAKING notes: the 0.30.4-beta one, plus the 0.30.3-beta one that was missing.
  • The complete docstring example showed a message format several releases old (Valid candidates:, Suggestion: Available descriptions: …). Since this PR changes that very message, it is replaced with the real current output. Drop this hunk if you would rather keep the diff to the fix.

No breaking change: error-message content only. Resolution behaviour, signatures, return values and the AmbiguousDescription field names are unchanged. candidates is the catalog again — what it was before 0.30.3-beta — and suggestion is multi-line on the closest-matches path.

🤖 Generated with Claude Code

…s list

Follow-up to #553. Its fix routed the similarity-filtered matches into
`candidates`, which `Exceptions/display.jl:158` labels `Available` -- so the
two message fields effectively swapped content: a 12-entry catalog was
reported as holding 5 descriptions, with nothing saying the list had been
filtered, while `Hint  Try one of the closest matches:` still ended on a
colon with nothing after it.

Two lines put each field back on its own job:

- `candidates` is always the catalog again -- every entry, or the first
  `max_show` followed by the `… and N more` marker;
- the closest matches are joined into `suggestion`, which the renderer
  already splits on newlines (`_print_pipe_field`), so `display.jl` needs no
  change.

This also makes #553's marker reachable. It is built from `all_candidates`,
which was discarded whenever `similar_descs` was non-empty, and
`_find_similar_descriptions` returns empty only when the request shares no
symbol with any description (Jaccard, filtered on > 0). The marker could
therefore only ever render for a catalog above `max_show` *and* a wholly
unknown request -- never in the case #553 was filed about.

Tests: new non-regression testset for #557 covering the branch #553 could
not reach (catalog > max_show *with* similar matches), the exhaustive
small-catalog path, a self-contained hint, and an end-to-end check that the
rendered message shows the matches after the `Hint` label. The #553 testset
asserted the behaviour this commit fixes (`candidates` equal to the closest
matches) and was corrected. Verified failing without the source change.

Also refreshed the `complete` docstring, whose example still showed a
message format several releases old.

Closes #557.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ocots ocots added bug Something isn't working run ci Trigger the CI workflow on this PR run documentation Trigger the Documentation workflow on this PR labels Sep 2, 2026
@ocots
ocots merged commit 355ae41 into main Sep 2, 2026
22 checks passed
@ocots
ocots deleted the fix/issue-557-available-hint branch September 2, 2026 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working run ci Trigger the CI workflow on this PR run documentation Trigger the Documentation workflow on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AmbiguousDescription: Available now lists the closest matches instead of what is available, and the Hint still promises a list it never prints

1 participant