Skip to content

fix(solve): init and initial_guess together raise "Conflicting aliases" in descriptive mode - #979

Merged
ocots merged 3 commits into
mainfrom
964-init-alias-conflict
Oct 13, 2026
Merged

ocots merged 3 commits into
mainfrom
964-init-alias-conflict

Conversation

@ocots

@ocots ocots commented Oct 13, 2026

Copy link
Copy Markdown
Member

Closes #964.

Problem

solve(ocp; init=1, initial_guess=2) in descriptive mode reported Unknown option :init with unrelated suggestions (:mu_init, :max_iter, …). Explicit mode already reported "Conflicting aliases". CTBase's route_all_options → Options.extract_option consumes the first alias found and leaves the other one in kwargs. The leftover alias is then routed to the strategies.

Change

  • The conflict check of _extract_action_kwarg is now its own helper, _check_action_aliases(kwargs, names) (src/helpers/kwarg_extraction.jl). Explicit mode calls it through _extract_action_kwarg, as before.
  • _route_descriptive_options calls it on _INITIAL_GUESS_ALIASES before route_all_options.
  • Docs, page "Initial guess", section "init or initial_guess": states the error raised in both modes instead of describing the bug.
  • CHANGELOG entry under [Unreleased].

Output after the fix, for the reproducer of the issue, both modes:

IncorrectArgument → _check_action_aliases, kwarg_extraction.jl:122
│  Conflicting aliases for the same option
│  Got       multiple aliases [:initial_guess, :init] provided simultaneously
│  Expected  at most one of (:initial_guess, :init)
│  Hint      Use only one alias at a time, e.g. `init=x0` or `initial_guess=x0`
└─

Choices made

  1. Check before routing, not extract before routing. The issue suggests extracting the action options before routing. I only check the aliases and leave extraction to route_all_options. Extracting display up front would bypass its documented priority rule with route_to (_descriptive_action_defs: a strategy can also declare display). The minimal check fixes the bug and changes nothing else.
  2. Only initial_guess/init is checked. It is the only action option with an alias; display has none. Adding an alias later means adding it to the call in _route_descriptive_options. I did not build a generic loop over _descriptive_action_defs() for a single case.
  3. Fixed here, not in CTBase. The root cause is generic: CTBase.Options.extract_option silently accepts two aliases of one option. That affects every strategy option with aliases (e.g. backend/adnlp_backend), not only the action options. A CTBase fix would need a release and a compat bump, so this PR fixes the user-visible bug now. A follow-up issue on CTBase is worth opening (not done here). Once fixed upstream, _check_action_aliases in descriptive mode becomes redundant but harmless.
  4. Same error, same context. The error text is unchanged (context="solve - action option extraction"), so both modes print the same message.

Tests

  • test/suite/helpers/test_kwarg_extraction.jl: unit tests of _check_action_aliases (none / one / both present).
  • test/suite/solve/test_descriptive_routing.jl: regression tests on _route_descriptive_options and solve_descriptive with init + initial_guess. They check that the message says "Conflicting aliases" and not "Unknown option": both are IncorrectArgument, so the type alone would not catch the bug.

Ran locally: test_kwarg_extraction, test_descriptive_routing and test_explicit give 171/171 passing. The issue's reproducer (without Ipopt, the error is raised before the solve) gives the output above in both modes. The full suite was not run locally.

🤖 Generated with Claude Code

ocots and others added 3 commits October 13, 2026 15:42
…criptive mode (#964)

route_all_options consumed the first alias and routed the leftover one to the
strategies, where it was rejected as an unknown option. The alias check of
_extract_action_kwarg is now a helper, _check_action_aliases, called by both
modes before any routing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rror in both modes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ocots
ocots merged commit 8fc04a2 into main Oct 13, 2026
3 checks passed
@ocots
ocots deleted the 964-init-alias-conflict branch October 13, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

init and initial_guess together: clear error in explicit mode, "unknown option :init" in descriptive mode

1 participant