Skip to content

Do not identify FLUX ControlNet checkpoints as FLUX main models - #9835

Merged
lstein merged 6 commits into
invoke-ai:mainfrom
chiliec:fix/flux-xlabs-controlnet-not-main
Oct 17, 2026
Merged

lstein merged 6 commits into
invoke-ai:mainfrom
chiliec:fix/flux-xlabs-controlnet-not-main

Conversation

@chiliec

@chiliec chiliec commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Installing an XLabs FLUX ControlNet checkpoint (e.g. flux-canny-controlnet-v3.safetensors from
XLabs-AI/flux-controlnet-collections) registered it as a FLUX main model (type: main,
base: flux, format: checkpoint) instead of a ControlNet, so it never appeared where ControlNets
are chosen and could not be used.

The XLabs ControlNet contains two FLUX double blocks, so its state dict carries
double_blocks.0.img_attn.norm.key_norm.scale — the key Main_Checkpoint_FLUX_Config._validate_is_flux
keys off. ControlNet_Checkpoint_FLUX_Config matches too, and because
ModelConfigFactory.matches_sort_key ranks ModelType.Main first, the main config won the tie-break.

_validate_is_flux now rejects state dicts that is_state_dict_xlabs_controlnet or
is_state_dict_instantx_controlnet recognise, so only the ControlNet config matches these files.

Related Issues / Discussions

Closes #9832

QA Instructions

New regression test tests/backend/model_manager/configs/test_flux_controlnet_not_main_config.py
builds a state dict mirroring the XLabs ControlNet (the controlnet-specific keys plus two FLUX double
blocks, no single_blocks/final_layer) and asserts the main config rejects it while the ControlNet
config accepts it.

python -m pytest tests/backend/model_manager/configs/test_flux_controlnet_not_main_config.py
  • Before the fix: test_xlabs_controlnet_does_not_match_flux_main fails (DID NOT RAISE NotAMatchError —
    the file matched as a main model).
  • After the fix: both tests pass (2 passed).

Verified locally on a CPU-only Linux box (Python 3.12, torch 2.13.0+cpu). The FLUX/ControlNet/main
config tests pass (67 passed, 1 skipped); the remaining failures in the wider
tests/backend/model_manager/configs/ directory are pre-existing on a clean main in this
environment (protobuf/onnx and WAN filename-heuristic env issues) — the same count fails with and
without this change.

Review

Smallest fix at the root cause: two is_state_dict_*_controlnet detectors already exist and are used
by the ControlNet config; reusing them in the main-model guard keeps behavior consistent and avoids
touching the fragile ControlNet key heuristics.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@github-actions github-actions Bot added python PRs that change python files backend PRs that change backend files python-tests PRs that change python tests labels Oct 13, 2026
@Pfannkuchensack Pfannkuchensack self-assigned this Oct 13, 2026
@Pfannkuchensack
Pfannkuchensack self-requested a review October 13, 2026 21:14
@Pfannkuchensack

Copy link
Copy Markdown
Member

Thanks! Verified with the real flux-canny-controlnet-v3.safetensors: on main both ControlNet_Checkpoint_FLUX_Config and Main_Checkpoint_FLUX_Config match and main wins; with this PR only the ControlNet config matches. Real FLUX.1 checkpoints (flux1-dev-fp8, raw and scaled) are still identified as FLUX main models, and the new test fails without the fix.

One change before merging: the is_state_dict_instantx_controlnet check in _validate_is_flux can't be reached. InstantX ControlNets use diffusers keys (transformer_blocks.*, controlnet_x_embedder.*) and have no double_blocks.0.img_attn.norm.key_norm.scale, so the key check just above already rejects them. Please drop it and keep only the XLabs check, unless you have a real InstantX file with BFL double_blocks keys.

Otherwise this looks good to me.

Pfannkuchensack and others added 2 commits October 13, 2026 23:40
…n validation

InstantX ControlNets use diffusers keys and have no BFL double_blocks key,
so the key check above already rejects them.

@Pfannkuchensack Pfannkuchensack left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to clean up the conflict but nice work.

@lstein
lstein enabled auto-merge October 17, 2026 01:19
@lstein
lstein merged commit ac27b56 into invoke-ai:main Oct 17, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend PRs that change backend files python PRs that change python files python-tests PRs that change python tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]: XLabs FLUX ControlNet v3 checkpoints are installed as FLUX main models

3 participants