Skip to content

Make disconnect() symmetric with connect(), and cover two remaining wrapper sites - #133

Merged
walterxie merged 1 commit into
mcmcfrom
mcmc-connect-disconnect-symmetry
Aug 11, 2026
Merged

Make disconnect() symmetric with connect(), and cover two remaining wrapper sites#133
walterxie merged 1 commit into
mcmcfrom
mcmc-connect-disconnect-symmetry

Conversation

@alexeid

@alexeid alexeid commented Aug 11, 2026

Copy link
Copy Markdown
Member

Follow-up to #132 (review findings), targeting mcmc so it lands inside that PR rather than separately. See #131.

1. disconnect() never got the inner-"mcmc" redirect

connect() gained the redirect in f6a369c; disconnect() did not. scrubAll() calls the two as the branches of a single decision:

} else if (connector.isActivated(...)) {
    connect(connector, context);
} else {
    disconnect(connector, context);
}

So with a wrapper Runnable, objects get connected to the inner MCMC but are never removed from it again: disconnect() resolves the wrapper, target.getInput(inputName) throws IllegalArgumentException, and the surrounding catch-and-print swallows it. The failure is silent — toggling a checkbox off, deleting a partition, or switching a clock model leaves stale operators/loggers on the inner MCMC and the generated XML is wrong rather than crashy.

Extracted the redirect as redirectToInnerMCMC() and used it from both, with a javadoc note that it must stay used by both.

Also gave disconnect(BeautiConnector, PartitionContext) the targetID='mcmc' -> mcmc.get().getID() translation connect(BeautiConnector, ...) already has. This is a no-op for the shipped templatesStandard.xml declares <run spec="beast.base.inference.MCMC" id="mcmc">, so the translation resolves to the same string — but it matters for a wrapper template whose runnable carries a different ID.

2. Two remaining sites that assume MCMC's inputs

These read MCMC inputs off doc.mcmc.get() without a cast, so the (MCMC) sweep didn't catch them, but they fail the same way — getInput()/setInputValue() throw IllegalArgumentException for an unknown input name (BEASTInterface.java:413):

Both routed through doc.getMCMC(), following the null-guard style already used elsewhere in #132.

Verification

  • mvn -o -pl beast-fx -am -DskipTests compile clean.
  • Headless BEAUti tests: BeautiMRCAPriorTest 1/1 pass, LinkUnlinkTest 14 run / 0 failures / 7 skipped (pre-existing @Disabled). BUILD SUCCESS.

Not addressed here

Null handling across #132 is still split roughly half-and-half — BeautiDoc:1595/:1641 (getMCMC().posteriorInput.get() in scrubAll/setUpActivePlugins) and the deepCopyPlugin call sites will NPE where other sites carefully guard. That's a contract decision for you: either those are bugs, or the guards are dead code and getMCMC() should throw a named IllegalStateException instead of returning null. Left alone deliberately so this PR stays reviewable.

…rapper sites #131

BeautiDoc: the inner-"mcmc" redirect added in f6a369c was applied to connect()
only. scrubAll() calls connect() and disconnect() as the two branches of one
decision, so with a wrapper Runnable objects were connected to the inner MCMC
but never removed from it again -- disconnect() resolved the wrapper, and
getInput(inputName) threw IllegalArgumentException into the catch-and-print,
silently doing nothing. Extract the redirect as redirectToInnerMCMC() and use
it from both. Also give disconnect(BeautiConnector, PartitionContext) the same
targetID='mcmc' -> runnable ID translation connect() already has; this is a
no-op for the shipped templates, whose runnable is literally id="mcmc".

OperatorListInputEditor and MRCAPriorInputEditor read MCMC inputs off
doc.mcmc.get() without a cast ("operatorschedule", "operator"), so they were
missed by the cast sweep, but they fail the same way: getInput()/setInputValue()
throw IllegalArgumentException for an unknown input name. Route both through
doc.getMCMC(). This is what still broke the Operators panel and the tip-date
sampling toggle for a PathSampler-style runnable.
@walterxie
walterxie merged commit 6c47bbb into mcmc Aug 11, 2026
@walterxie
walterxie deleted the mcmc-connect-disconnect-symmetry branch August 12, 2026 03:17
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.

2 participants