Skip to content

Reject multi-block time-dependent SCCNonlinearProblem with a clear error - #5182

Draft
ChrisRackauckas-Claude wants to merge 8 commits into
SciML:masterfrom
ChrisRackauckas-Claude:scc-two-blocks
Draft

ChrisRackauckas-Claude wants to merge 8 commits into
SciML:masterfrom
ChrisRackauckas-Claude:scc-two-blocks

Conversation

@ChrisRackauckas-Claude

@ChrisRackauckas-Claude ChrisRackauckas-Claude commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Fixes #5174.

Multi-block SCCNonlinearProblem on a compiled algebraic System with an
independent variable previously indexed the parameter tuple out of bounds. Per
review, do not silently rewrite the system: require a time-independent system
(or convert with mtkcompile(NonlinearSystem(sys))) before the multi-block path.

Single-block (and empty) systems still fall through to NonlinearProblem /
HomotopyProblem / LinearProblem as on master, including the silent
NonlinearSystem conversion those constructors already perform.

The issue #5174 reproducer (two independent blocks, combine_sccs = false) now
gets a clear SystemCompatibilityError naming the conversion; after
mtkcompile(NonlinearSystem(sys)) it solves to y = 3, z = 4.

Verification

Regression test/scc_two_blocks_regression.jl: multi-block timedep throws;
single-block timedep returns a successful NonlinearProblem; converted multi-block
solves. Full test/scc_nonlinear_problem.jl: SCC two-blocks | 20/20,
SCC_FILE_PASSED. Runic --check on touched files: clean.

Please ignore this draft until reviewed by @ChrisRackauckas.

Adoption update

Rebased onto origin/master (0459027b88). Addressed @AayushSabharwal by failing
check_compatibility instead of silent rewrite. Follow-up review (Opus 5.5 CHANGES):

  1. Moved the time-independence check to after the single-SCC / empty fallbacks.
  2. Reused check_time_independent with suggest_disable = false so the message does
    not advertise check_compatibility = false (that opt-out now converts via
    mtkcompile(NonlinearSystem(sys)) instead of BoundsError). Extended
    SystemCompatibilityError with an optional suggest_disable flag.
  3. Title/body updated to describe the error-based multi-block behaviour; Fixes #5174
    remains correct (clear error for the reporter case; working path after conversion).

Fail-before / pass-after (earlier adoption of the error path)

With the multi-block check absent: 12 passed, 2 failed (SystemCompatibilityError
not thrown). With the check: 14/14, later 20/20 after adding the single-block test.

CI classification (prior PR head vs master)

QA reexports, SciMLBase/NeuralPDE/SciMLSensitivity IntegrationTest, and
downgrade-mtkbase Optimization failures also occur on master
(0459027b88 Tests / IntegrationTest / Downgrade Sublibraries runs). Docs linkcheck
was flaky vs green Documentation on master.

Not verified

  • Full GROUP=InterfaceII via Pkg.test under a clean depot (SCC file run instead).
  • Fresh CI on this head after push.

Risk assessment

  • Risk: low
  • Blast radius: SCCNonlinearProblem construction. The time-independence compatibility check (through ModelingToolkitBase's check_time_independent) now applies only on the multi-block SCC path. Empty systems and the single-SCC fallback behave as on master. A multi-block time-dependent system now gets a clear SystemCompatibilityError naming mtkcompile(NonlinearSystem(sys)) instead of a BoundsError. No public API change.
  • Evidence: a coupled single-block time-dependent system builds a NonlinearProblem and solves identically to master. Multi-block: master throws a BoundsError; the PR throws the clear error, or with check_compatibility=false converts and solves (u1=2, u2=1.44225). Initialization with use_scc=true is unchanged. scc_two_blocks_regression.jl passes 20/20, and all 10 CI reds also fail on master.
  • Independent review: Claude Code (Opus 5.5; adopted by Cursor Auto), two rounds. Round 1: medium, CHANGES (check placement, duplicate check, stale title). Round 2: low, high confidence, MERGE. Its two nits landed in 948c123 and were checked by the head session.
  • Merge: auto-merge candidate. It follows the maintainer's review request to fail check_compatibility rather than rewrite silently.

Risk assessment and review coordination by 🤖 Claude Code (model: claude-opus-5-5[1m]), https://claude.ai/code/session_01NdFVhANTF4nepTbqYxjfRP

Risk assessment

  • Risk: medium
  • Blast radius: Multi-block SCCNonlinearProblem construction and shared compatibility errors. Public constructor behavior changes: time-dependent systems are rejected by default; check_compatibility=false recompiles them. This can qualify as a bug fix, but the description’s “No public API change” needs qualification. No tests were weakened.
  • Evidence: Head 948c123 has 10 failures, all also failing on recent master commits da8e682 and 0459027; inspected head/latest-master logs show matching failures. Pre-existing: tests / Optimization (Julia 1 and lts), sublibrary-ci / lib/ModelingToolkitBase [Optimization] (Julia 1 and lts), and downgrade-mtkbase (Optimization)—constraint Hessian, AmplNLWriter, and Ipopt failures; tests / QA—unapproved reexports; sublibrary-ci / lib/ModelingToolkitBase [QA]—the same 234 JET diagnostics; SciMLBase.jl/SymbolicIndexingInterface/1/—missing SCC u0; NeuralPDE.jl/NNPDE2/1/—Enzyme activity error; SciMLSensitivity.jl/Core8/1/—matching Enzyme/Mooncake errors. No observed CI test regressions. InterfaceII passes. Comparison runs: Tests, Sublibrary CI, Downgrade Sublibraries, IntegrationTest.
  • Independent review: Codex CLI 0.156.1 / gpt-6-astra rated it medium, high confidence: CI failures are pre-existing, but the change depends on new dependency-internal keywords without tightening compatibility and leaves its automatic conversion branch untested.
  • Merge: needs human review (new use of non-public ModelingToolkitBase check_time_independent and extension of non-public check_compatible_system; unchanged ModelingToolkitBase = "1.76" permits released versions lacking the new keywords, implying an unsupported-keyword error—source-level finding, not locally executed; this dependency risk is undisclosed; add regression coverage for check_compatibility=false and document the constructor behavior/SemVer implications).

🤖 Risk assessment posted by an AI agent (fleet master) — harness: Codex CLI 0.156.1 / gpt-6-astra; dispatched by Claude Code head, model claude-opus-5-5[1m]
Conversation: local Claude Code session 3cd6500a-1f81-46b5-ac0b-c466e15b6a53 (session ID, no URL)

Agent follow-up

This follow-up commit changes the design described in the sections above. ModelingToolkitBase is no longer touched. SystemCompatibilityError gains no suggest_disable field, and check_time_independent gains no suggest_disable/msg keywords.

  • Why: the gpt-6-astra review above found that ModelingToolkit's ModelingToolkitBase = "1.77.1" compat bound allows released ModelingToolkitBase versions that lack those keywords. A ModelingToolkit release could resolve against one of them and throw a MethodError on the multi-block path. With the change kept inside ModelingToolkit, there is no compat floor to raise.
  • Now: after the empty / single-SCC fallbacks, SCCNonlinearProblem runs check_compatibility && check_compatible_system(SCCNonlinearProblem, sys). ModelingToolkit's method throws SystemCompatibilityError("SCCNonlinearProblemwith multiple SCCs requires a time-independent system. Convert it withmtkcompile(NonlinearSystem(sys)) first.").
  • check_compatibility = false skips the check, as it does for every other problem constructor. It no longer recompiles the system silently: the user does the conversion, as @AayushSabharwal asked. The generic "To disable this check…" hint therefore appears again. Disabling the check on a multi-block time-dependent system reaches the same solve-time BoundsError as on master. Push back if you would rather keep the automatic conversion on the opt-out path.
  • check_compatibility is forwarded explicitly to process_SciMLProblem and the per-block SCCNonlinearFunction/LinearFunction. Master forwards it there through kwargs..., and capturing it as a named keyword had stopped that.
  • Merged current master, which brings in Update MTKBase tests and compat floors for Symbolics 7.43-7.45 #5281 (Symbolics 7.43/7.45 test updates). That PR fixes the lib/ModelingToolkitBase [InterfaceI] and [RegressionI] reds on the previous head.

Verification (Julia 1.13.2)

  • test/scc_two_blocks_regression.jl with src/problems/sccnonlinearproblem.jl reverted to master: SCC two-blocks | 17 passed, 3 failed. The 3 failures are err isa SystemCompatibilityError (Evaluated: nothing isa SystemCompatibilityError), the message check, and the combine_sccs = true @test_throws.
  • Same file with this change: SCC two-blocks | 20 20.
  • GROUP=InterfaceII julia --project -e 'using Pkg; Pkg.test()' on the pushed tree: InterfaceII | 1460 passed, 7 broken (pre-existing), 1467 total, exit 0.
  • Runic --check and typos on the changed files: clean.
  • Not run: GROUP=QA (no exports, dependencies, or public names changed; the only qualified access, MTKBase.check_compatible_system, is already in the QA ignore list).

CI on the previous head (25383784e5)

All 7 reds are pre-existing:

Risk

  • Risk: low.
  • Blast radius: only the multi-block SCCNonlinearProblem path for time-dependent systems, which crashed with a BoundsError on master. Time-independent systems and the single-SCC / empty fallbacks behave as on master.
  • Independent review: none yet of this follow-up commit. It still needs @AayushSabharwal's re-review.

🤖 Posted by an AI agent — harness: Claude Code 2.1.301 · model: claude-opus-5-5
Conversation: local session ID ec3d0300-24c6-4a77-ba04-c1622ff0e24b (headless, no URL)

@AayushSabharwal

Copy link
Copy Markdown
Member

I think this should just fail check_compatibility and require the user to do it? Silently changing the system is not great UX imo.

ChrisRackauckas and others added 2 commits September 26, 2026 14:59
SCCNonlinearProblem on a compiled algebraic System with an independent
variable indexed the parameter tuple out of bounds because the system was
never normalized to a time-independent nonlinear system.

Fixes SciML#5174.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Agent-Harness: Codex CLI 0.155.1 (patch and tests); Claude Code 2.1.278 (rebase, verification, PR)
Agent-Model: gpt-6-astra; claude-fable-5-1
Agent-Session: https://claude.ai/code/session_01VJtEvCkHe9XafoMbYvR9No
Per review, do not silently re-mtkcompile; require mtkcompile(NonlinearSystem(sys)).

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Cursor Agent <noreply@cursor.com>
Agent-Harness: Cursor Agent CLI 2026.09.26-dd393fe
Agent-Model: auto
Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/adopt/SciML_ModelingToolkit.jl-5182/log.txt on amdci2.julia.csail.mit.edu
Single-block time-dependent systems keep falling through to
NonlinearProblem as on master. Multi-block gets a clear error (no
check_compatibility=false hint); that opt-out converts safely instead.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Cursor Agent <noreply@cursor.com>
Agent-Harness: Cursor Agent CLI 2026.09.26-dd393fe
Agent-Model: auto
Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/adopt/SciML_ModelingToolkit.jl-5182/log.txt on amdci2.julia.csail.mit.edu
@ChrisRackauckas-Claude ChrisRackauckas-Claude changed the title Convert time-dependent systems before building SCCNonlinearProblem Reject multi-block time-dependent SCCNonlinearProblem with a clear error Sep 27, 2026
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Cursor Agent <noreply@cursor.com>
Agent-Harness: Cursor Agent CLI 2026.09.26-dd393fe
Agent-Model: auto
Agent-Session: local session, transcript at /home/crackauc/sandbox/goals/issue-backlog/adopt/SciML_ModelingToolkit.jl-5182/log.txt on amdci2.julia.csail.mit.edu
@AayushSabharwal

Copy link
Copy Markdown
Member

Merge conflicts

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Devin <noreply@cognition.ai>
Agent-Harness: Devin CLI 3000.11.3 (conflict resolution), Claude Code 2.1.285 (orchestration)
Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium
Agent-Session: local Claude session 3c311569-dda6-4687-bc9f-65febb212c33 (fleet master); Devin log /Users/chrisrackauckas/sandbox/master/fusion-fixes/SciML_ModelingToolkit.jl-5182/log.txt

# Conflicts:
#	src/problems/sccnonlinearproblem.jl
#	test/scc_nonlinear_problem.jl
@ChrisRackauckas

Copy link
Copy Markdown
Member

🤖 Automated comment from an AI agent running as @ChrisRackauckas — not written or reviewed by Chris.

Merged the default branch into this PR to resolve conflicts (head 3ca6499). Re-review the resolution before merging.

Conflict resolution report

STATUS: RESOLVED

Merge of origin/master into scc-two-blocks (#5182) committed as 3ca6499ae ("Merge master into scc-two-blocks"). No follow-up commit was needed. Nothing was pushed.

Conflicting files

  • src/problems/sccnonlinearproblem.jl: the conflict was in the empty-var_sccs fallback call to TProb{iip, specialize}(...). The PR adds check_compatibility and master (Handle SCCNonlinearProblem with no remaining unknowns #5183 and follow-ups) adds jac = true. I kept both as check_compatibility, jac = true, kwargs.... Master's other changes to this file (is_structurally_unbalanced_error, the fallback in steady_state_sccprob) and the PR's multi-block time-dependence check merged cleanly and are both still in the file.
  • test/scc_nonlinear_problem.jl: the conflict was in the trailing includes. I kept all three: the PR's scc_two_blocks_regression.jl and master's scc_zero_state_regression.jl and scc_array_cache_regression.jl.

Runic (julia +1.12 --project=@runic -m Runic -i) was run on both files.

Tests

  • julia --project -e 'using Pkg; Pkg.instantiate()': OK
  • The root Project.toml holds the test deps as [extras]/[targets], so the test file was run through TestEnv from a temp env. No tracked files were changed:
    julia -e 'using Pkg; Pkg.activate(;temp=true); Pkg.add("TestEnv"); using TestEnv; Pkg.activate("."); TestEnv.activate(); include(joinpath("test","scc_nonlinear_problem.jl"))'
    Result: 196/196 passed, 0 failed, 0 errored, exit code 0. This includes:
    • SCC two-blocks (the PR's tests): 20/20
    • SCC zero-state (master): 14/14
    • SCC array-cache (master): 8/8
    • All other testsets in the file passed, e.g. the SteadyStateProblem SCC lowering regressions at 51/51.
    • Log: scratch/scc_test.log

No Julia processes started by this run are still running.


🤖 Posted by an AI agent — harness: Devin CLI 3000.11.3 (merge), Claude Code 2.1.285 (posting) · model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium
Conversation: local Claude session 3c311569-dda6-4687-bc9f-65febb212c33 (fleet master)

ChrisRackauckas and others added 3 commits October 16, 2026 05:00
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Harness: Claude Code 2.1.301
Agent-Model: claude-opus-5-5
Agent-Session: local session ID ec3d0300-24c6-4a77-ba04-c1622ff0e24b (headless claude -p, no URL)
Throw SystemCompatibilityError from ModelingToolkit's own
check_compatible_system method for SCCNonlinearProblem instead of adding
`suggest_disable`/`msg` keywords to ModelingToolkitBase internals. The
released ModelingToolkitBase versions allowed by ModelingToolkit's compat
bound lack those keywords, so a release of this branch could have paired
with them and thrown a MethodError on the multi-block path.

`check_compatibility = false` now skips the check, as it does for every
other problem constructor, instead of silently recompiling the system with
`mtkcompile(NonlinearSystem(sys))`; the user does that conversion, which is
what the error message names. `check_compatibility` is forwarded to
`process_SciMLProblem` and the per-block functions, as it was through
`kwargs...` before the keyword was captured.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Harness: Claude Code 2.1.301
Agent-Model: claude-opus-5-5
Agent-Session: local session ID ec3d0300-24c6-4a77-ba04-c1622ff0e24b (headless claude -p, no URL)

This branch has not been deployed

No deployments
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.

SCC solve of algebraic System with independent variable indexes parameter tuple out of bounds

3 participants