# Buggy code
def create(
    self,
    trans,
    parent,
    name,
    collection_type,
    element_identifiers=None,
    elements=None,
    implicit_collection_info=None,
    trusted_identifiers=None,
    hide_source_items=False,
    tags=None,
):
    """
    PRECONDITION: security checks on ability to add to parent
    occurred during load.
    """
    # Trust embedded, newly created objects created by tool subsystem.
    if trusted_identifiers is None:
        trusted_identifiers = implicit_collection_info is not None

    if element_identifiers and not trusted_identifiers:
        validate_input_element_identifiers(element_identifiers)

    dataset_collection = self.create_dataset_collection(
        trans=trans,
        collection_type=collection_type,
        element_identifiers=element_identifiers,
        elements=elements,
        hide_source_items=hide_source_items,
    )

    if isinstance(parent, model.History):
        dataset_collection_instance = self.model.HistoryDatasetCollectionAssociation(
            collection=dataset_collection,
            name=name,
        )
        if implicit_collection_info:
            for input_name, input_collection in implicit_collection_info[
                "implicit_inputs"
            ]:
                dataset_collection_instance.add_implicit_input_collection(
                    input_name, input_collection
                )
            for output_dataset in implicit_collection_info.get("outputs"):
                if output_dataset not in trans.sa_session:
                    output_dataset = trans.sa_session.query(type(output_dataset)).get(
                        output_dataset.id
                    )
                if isinstance(output_dataset, model.HistoryDatasetAssociation):
                    output_dataset.hidden_beneath_collection_instance = (
                        dataset_collection_instance
                    )
                elif isinstance(
                    output_dataset, model.HistoryDatasetCollectionAssociation
                ):
                    dataset_collection_instance.add_implicit_input_collection(
                        input_name, input_collection
                    )
                else:
                    # dataset collection, don't need to do anything...
                    pass
                trans.sa_session.add(output_dataset)

            dataset_collection_instance.implicit_output_name = implicit_collection_info[
                "implicit_output_name"
            ]

        log.debug(
            "Created collection with %d elements"
            % (len(dataset_collection_instance.collection.elements))
        )
        # Handle setting hid
        parent.add_dataset_collection(dataset_collection_instance)

    elif isinstance(parent, model.LibraryFolder):
        dataset_collection_instance = self.model.LibraryDatasetCollectionAssociation(
            collection=dataset_collection,
            folder=parent,
            name=name,
        )

    else:
        message = (
            "Internal logic error - create called with unknown parent type %s"
            % type(parent)
        )
        log.exception(message)
        raise MessageException(message)
    tags = tags or {}
    if implicit_collection_info:
        for k, v in implicit_collection_info.get("implicit_inputs", []):
            for tag in [t for t in v.tags if t.user_tname == "name"]:
                tags[tag.value] = tag
    for _, tag in tags.items():
        dataset_collection_instance.tags.append(tag.copy())

    return self.__persist(dataset_collection_instance)


# Traceback (KeyError)
galaxy.tools.actions INFO 2017-11-10 17:17:20,507 Verified access to datasets for Job[unflushed,tool_id=toolshed.g2.bx.psu.edu/repos/lparsons/htseq_count/htseq_count/0.6.1galaxy3] (39.007 ms)
galaxy.tools.actions INFO 2017-11-10 17:17:20,511 Setup for job Job[unflushed,tool_id=toolshed.g2.bx.psu.edu/repos/lparsons/htseq_count/htseq_count/0.6.1galaxy3] complete, ready to flush (67.715 ms)
galaxy.tools.actions INFO 2017-11-10 17:17:20,608 Flushed transaction for job Job[id=2195981,tool_id=toolshed.g2.bx.psu.edu/repos/lparsons/htseq_count/htseq_count/0.6.1galaxy3] (96.495 ms)
galaxy.tools.execute DEBUG 2017-11-10 17:17:20,608 Tool [toolshed.g2.bx.psu.edu/repos/lparsons/htseq_count/htseq_count/0.6.1galaxy3] created job [2195981] (631.589 ms)
galaxy.tools.execute DEBUG 2017-11-10 17:17:20,629 Executed 2 job(s) for tool toolshed.g2.bx.psu.edu/repos/lparsons/htseq_count/htseq_count/0.6.1galaxy3 request: (1092.059 ms)
galaxy.managers.collections DEBUG 2017-11-10 17:17:20,662 Created collection with 2 elements
galaxy.managers.collections DEBUG 2017-11-10 17:17:20,812 Created collection with 2 elements
galaxy.workflow.run DEBUG 2017-11-10 17:17:21,068 Workflow step 137193 of invocation 29732 invoked (1794.676 ms)
galaxy.managers.collections DEBUG 2017-11-10 17:17:21,479 Created collection with 0 elements
galaxy.tools ERROR 2017-11-10 17:17:21,510 Exception caught while attempting tool execution:
Traceback (most recent call last):
File "/usr/local/galaxy/galaxy-dist/lib/galaxy/tools/__init__.py", line 1311, in handle_single_execution
job, out_data = self.execute(trans, incoming=params, history=history, rerun_remap_job_id=rerun_remap_job_id, mapping_over_collection=mapping_over_collection, execution_cache=execution_cache)
File "/usr/local/galaxy/galaxy-dist/lib/galaxy/tools/__init__.py", line 1391, in execute
return self.tool_action.execute(self, trans, incoming=incoming, set_output_hid=set_output_hid, history=history, **kwargs)
File "/usr/local/galaxy/galaxy-dist/lib/galaxy/tools/actions/__init__.py", line 410, in execute
**element_kwds
File "/usr/local/galaxy/galaxy-dist/lib/galaxy/tools/actions/__init__.py", line 735, in create_collection
**element_kwds
File "/usr/local/galaxy/galaxy-dist/lib/galaxy/managers/collections.py", line 107, in create
dataset_collection_instance.tags.append(tag.copy())
File "/usr/local/galaxy/galaxy-dist/.venv/lib/python2.7/site-packages/sqlalchemy/orm/collections.py", line 1073, in append
item = __set(self, item, _sa_initiator)
File "/usr/local/galaxy/galaxy-dist/.venv/lib/python2.7/site-packages/sqlalchemy/orm/collections.py", line 1045, in __set
item = executor.fire_append_event(item, _sa_initiator)
File "/usr/local/galaxy/galaxy-dist/.venv/lib/python2.7/site-packages/sqlalchemy/orm/collections.py", line 717, in fire_append_event
item, initiator)
File "/usr/local/galaxy/galaxy-dist/.venv/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 941, in fire_append_event
initiator or self._append_token or self._init_append_token())
File "/usr/local/galaxy/galaxy-dist/.venv/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 1178, in emit_backref_from_collection_append_event
child_impl = child_state.manager[key].impl
KeyError: 'dataset_collections'

# Fixed code
def create(
    self,
    trans,
    parent,
    name,
    collection_type,
    element_identifiers=None,
    elements=None,
    implicit_collection_info=None,
    trusted_identifiers=None,
    hide_source_items=False,
    tags=None,
):
    """
    PRECONDITION: security checks on ability to add to parent
    occurred during load.
    """
    # Trust embedded, newly created objects created by tool subsystem.
    if trusted_identifiers is None:
        trusted_identifiers = implicit_collection_info is not None

    if element_identifiers and not trusted_identifiers:
        validate_input_element_identifiers(element_identifiers)

    dataset_collection = self.create_dataset_collection(
        trans=trans,
        collection_type=collection_type,
        element_identifiers=element_identifiers,
        elements=elements,
        hide_source_items=hide_source_items,
    )

    if isinstance(parent, model.History):
        dataset_collection_instance = self.model.HistoryDatasetCollectionAssociation(
            collection=dataset_collection,
            name=name,
        )
        if implicit_collection_info:
            for input_name, input_collection in implicit_collection_info[
                "implicit_inputs"
            ]:
                dataset_collection_instance.add_implicit_input_collection(
                    input_name, input_collection
                )
            for output_dataset in implicit_collection_info.get("outputs"):
                if output_dataset not in trans.sa_session:
                    output_dataset = trans.sa_session.query(type(output_dataset)).get(
                        output_dataset.id
                    )
                if isinstance(output_dataset, model.HistoryDatasetAssociation):
                    output_dataset.hidden_beneath_collection_instance = (
                        dataset_collection_instance
                    )
                elif isinstance(
                    output_dataset, model.HistoryDatasetCollectionAssociation
                ):
                    dataset_collection_instance.add_implicit_input_collection(
                        input_name, input_collection
                    )
                else:
                    # dataset collection, don't need to do anything...
                    pass
                trans.sa_session.add(output_dataset)

            dataset_collection_instance.implicit_output_name = implicit_collection_info[
                "implicit_output_name"
            ]

        log.debug(
            "Created collection with %d elements"
            % (len(dataset_collection_instance.collection.elements))
        )
        # Handle setting hid
        parent.add_dataset_collection(dataset_collection_instance)

    elif isinstance(parent, model.LibraryFolder):
        dataset_collection_instance = self.model.LibraryDatasetCollectionAssociation(
            collection=dataset_collection,
            folder=parent,
            name=name,
        )

    else:
        message = (
            "Internal logic error - create called with unknown parent type %s"
            % type(parent)
        )
        log.exception(message)
        raise MessageException(message)
    tags = tags or {}
    if implicit_collection_info:
        for k, v in implicit_collection_info.get("implicit_inputs", []):
            for tag in [t for t in v.tags if t.user_tname == "name"]:
                tags[tag.value] = tag
    for _, tag in tags.items():
        dataset_collection_instance.tags.append(
            tag.copy(cls=model.HistoryDatasetCollectionTagAssociation)
        )

    return self.__persist(dataset_collection_instance)