HADDOCK on multi-chain receptor: how to approach?

Hi Bonvin Lab people!

First of all, let me tell you that I am very new to this topic and I might be quite wrong in some of the formulations here. Please don’t mind that and correct me if I am wrong!

I am setting up a docking experiment between a membrane receptor and an antibody. The receptor is a multimeric complex composed of six chains, each containing a transmembrane α-helix. I would like to exclude the transmembrane regions from the docking search space and instead define ambiguous interaction restraints for the extramembranous domains. However, because this is a multichain receptor, I am unsure how best to construct and combine these restraints. The antibody may interact simultaneously with surface residues from two or three chains, given that they are very near to each other, so restricting the docking to individual chains independently would not reflect a realistic binding scenario. Apart from excluding alpha helices, I am not aware of any experimental clues on where binding could happen, so I am not sure if I can add any other restraints.

Environment: Python 3.11, Haddock3 2025.8.0

What I’ve tried so far:

  • I manually find helices in the receptor and note them down
  • I find the surface residues of the receptor using haddock3-restraints calc_accessibility and remove the helices from this list
  • using these surface residues as active restraints, I get the passive restraints using haddock3-restraints passive_from_active
  • when I have active and passive restraints, I define .actpass files for each chain of the receptor
  • for the antibody, I find the surface residues and define them as passive only and put them in the second line of the .actpass file, with the first line being empty
  • I convert these to .tbl files using haddock3-restraints active_passive_to_ambing making sure to define the --segid-one and --segid-two as the chain labels of the receptor and the antibody, respectively
  • I combine these .tbl to a single .tgz file (it took some time to realize that the .tgz file has to have a very specific name)

My HADDOCK steps in the config file then look like this:

[topoaa]

[rigidbody]
ambig_fname = "../haddock/ambig.tbl.tgz"
ranair = true
sampling = 1000
randremoval = true #  default: true
tolerance = 5

What happens?

  • [topoaa] works well
  • [rigidbody] fails with the following error:
[2025-09-08 09:59:46,041 base_cns_module INFO] Running [rigidbody] module
[2025-09-08 09:59:46,041 __init__ INFO] [rigidbody] crossdock=true
[2025-09-08 09:59:46,042 __init__ INFO] [rigidbody] Preparing jobs...
[2025-09-08 09:59:46,047 libutil INFO] Selected 10 cores to process 100 jobs, with 10 maximum available cores.
[2025-09-08 09:59:46,047 libparallel INFO] Using 10 cores
[2025-09-08 09:59:46,275 libparallel INFO] 100 tasks finished
[2025-09-08 09:59:46,278 __init__ INFO] [rigidbody] Running CNS Jobs n=100
[2025-09-08 09:59:46,278 libutil INFO] Selected 10 cores to process 100 jobs, with 10 maximum available cores.
[2025-09-08 09:59:46,279 libparallel INFO] Using 10 cores
[2025-09-08 09:59:56,617 libparallel INFO] 100 tasks finished
[2025-09-08 09:59:56,618 __init__ INFO] [rigidbody] CNS jobs have finished
[2025-09-08 09:59:56,686 libutil ERROR] 100.00% of output was not generated for this module and tolerance was set to 5.00%.
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/haddock/libs/libutil.py", line 378, in log_error_and_exit
    yield
  File "/usr/local/lib/python3.11/site-packages/haddock/clis/cli.py", line 193, in main
    workflow.run()
  File "/usr/local/lib/python3.11/site-packages/haddock/libs/libworkflow.py", line 43, in run
    step.execute()
  File "/usr/local/lib/python3.11/site-packages/haddock/libs/libworkflow.py", line 173, in execute
    self.module.run()  # type: ignore
    ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/haddock/modules/base_cns_module.py", line 61, in run
    self._run()
  File "/usr/local/lib/python3.11/site-packages/haddock/modules/sampling/rigidbody/__init__.py", line 271, in _run
    self.export_io_models(faulty_tolerance=self.params["tolerance"])
  File "/usr/local/lib/python3.11/site-packages/haddock/modules/__init__.py", line 309, in export_io_models
    self.finish_with_error(_msg)
  File "/usr/local/lib/python3.11/site-packages/haddock/modules/__init__.py", line 317, in finish_with_error
    raise RuntimeError(reason)
RuntimeError: 100.00% of output was not generated for this module and tolerance was set to 5.00%.
[2025-09-08 09:59:56,691 libutil ERROR] 100.00% of output was not generated for this module and tolerance was set to 5.00%.
[2025-09-08 09:59:56,691 libutil ERROR] An error has occurred, see log file. And contact the developers if needed.
[2025-09-08 09:59:56,693 libutil INFO] Finished at 08/09/2025 09:59:56. For any help contact us at https://github.com/haddocking/haddock3/issues. Agur! Adiós! Adéu-siau!.

Doubts

  • Is this the right approach at all? Should I do something inherently different since I have multiple chains and I don’t have much information about possible binding sites?
  • Why does this error happen? What can I do about it? I am quite sure it’s about my configuration and it is not a bug.

Let me know if you need any further information, explanation or anything else from my side.

Thanks in advance!

Hi there

A few tips:

  1. It is best to define your receptor as a single chain. For that you should for example shift the numbering of each chain to avoid overlap in numbering. And combine them all as a single chain.
    This is also important from a scoring perspective as the HADDOCK score is calculated over all interfaces. Check for example our antibody-antigen tutorial on how to do this renumbering using our PDB-tools.

[

Antibody-antigen modelling tutorial using a local version of HADDOCK3
bonvinlab.org

](https://www.bonvinlab.org/education/HADDOCK3/HADDOCK3-antibody-antigen/)
  1. If you have no idea where the antibody is binging, best would be to select indeed all solvent accessible residues, excluding your transmembrane region and define those as passive.
    As this might be a very large number of residues, to speed up the calculations you might consider limiting the restraint to e.g. CA atoms. Might need some manual editing (or check the haddock k-restraints options).

  2. Define restraints in between your receptor chains (even if a single chain) to keep those together (can be done with the haddock-restraints restraint command)

  3. For your antibody define the CDR residues as active

  4. Increase the sampling significantly. An example configuration file for a rather similar protocols would be the one in the haddock3 examples:

docking-antibody-antigen-CDR-accessible-clt-full.cfg