TypeError: 'Sentinel' object is not iterable when running butler query commands in r29.2.0 (RSP Build 2630)

I am experiencing an issue in my Jupyter Notebook environment when running some butler query commands. For example:

!butler query-dataset-types --verbose $LOCAL_REPO

!butler query-collections --chains 'TREE' $LOCAL_REPO

The error message returned is:

TypeError: 'Sentinel' object is not iterable

This problem appears in:

Release r29.2.0 (RSP Build 2630)
lsst_distrib          gc675d380bf+f75de59d28 	v29_2_0_rc1 v29_2_0 current setup
Python 3.12.11

However, when I switch to:

lsst_distrib          g00e868bf88+b3738ef47e 	w_2026_08 w_latest current setup
Python 3.13.9

the issue disappears and the same commands work correctly.

Additional context

*The error seems to be specific to r29.2.0.

  • It is not clear whether the root cause is related to the Python version (3.12.11 vs 3.13.9) or to changes in the Science Pipelines between r29.2.0 and w_2026_08.
  • I’am pressent the same error using a local repository ($LOCAL_REPO).

Questions

  • Is this a known issue in r29.2.0?
  • Is it related to Python 3.12?
  • Is there a recommended workaround besides switching to a newer weekly?

Is there more of an error message?

Thank you for the report. We were able to reproduce and it turns out that the container image was rebuilt recently and a dependency was inadvertently upgraded. We fixed the bug in butler code 6 months ago that dealt with this problem but 29.2 is older than that.

We will try to rebuild the image to restore the dependency version.

As an aside, you will get much better performance and more control if you create a Butler instance in python and call butler.registry.queryDatasetTypes directly. There is also a butler.collections API for you to query collections and examine them.

Hi Tim,

Thank you for your answer and for proposing a solution. I have been using the commented command to access the DatasetTypes, etc., as you suggested.

However, I am still encountering the same error message:

TypeError: 'Sentinel' object is not iterable

Initially, this happened when running

butler query-* commands

Now it also appears when executing processing-related commands, for example:

!butler register-instrument ./local_butler lsst.obs.lsst.LsstComCam

I am also seeing similar failures when running pipeline tasks such as:
• makeDirectWarp
• assembleDeepCoadd

For reference, here is the routine I am using to register instruments from a remote repository:

def instrument_register_from_remote(
    local_repo: str,
    remote_repo: str,
    instruments: set[str],
    remote_collection: str = "LSSTComCam/DP1",
    logger: logging.Logger = None,
) -> bool:
    """
    Register instruments in the local Butler repo using definitions
    retrieved from a remote repo.

    Parameters
    ----------
    instruments: set of instrument names (strings)
    remote_collection: collection to open the remote Butler with
    """
    if not instruments: raise RuntimeError("No instrument names provided.")
    if logger: logger.info(f"Detected instruments to register: {sorted(instruments)}") 
    if logger: logger.info(f"Opening remote Butler: {remote_repo} (collections={remote_collection})")
    
    remote = Butler(remote_repo, collections=remote_collection)

    # Get instrument records from remote registry
    remote_inst_records = [
        rec for rec in remote.registry.queryDimensionRecords("instrument")
        if rec.name in instruments
    ]

    found_names = {rec.name for rec in remote_inst_records}
    missing = instruments - found_names
    if missing and logger:
        logger.warning(f"Some instruments not found in remote registry: {sorted(missing)}")
        # still continue with those found; you can choose to raise instead

    # Full instrument class names (e.g., lsst.obs.lsst.LsstCam)
    instrument_full = [rec.class_name for rec in remote_inst_records]
    if logger:
        logger.debug(f"Instrument classes from remote: {instrument_full}")

    # Local registry
    local_registry = Butler(local_repo).registry
    local_instrument_names = {rec.name for rec in local_registry.queryDimensionRecords("instrument")}

    for rec, class_name in zip(remote_inst_records, instrument_full):
        if rec.name in local_instrument_names:
            if logger:
                logger.info(f"Instrument '{rec.name}' already registered locally — skipping.")
            continue

        cmd = ["butler", "register-instrument", local_repo, class_name]
        _run(cmd, logger=logger)
        if logger:
            logger.info(f"Registered instrument '{rec.name}' -> {class_name}")

    return True

This workflow was working perfectly last week. The error only started appearing after the most recent platform update.

I am wondering whether this is:
1. Related to the problem you mentioned, or
2. Related to the intermittent catalog query issues previously mentioned on https://data.lsst.cloud/.

Would you recommend waiting for the next platform update, or is there a known workaround for this version?

Thanks again for your help.