langgenius/dify · error · ValueError

Dataset Collection Binding not found

Error message

Dataset Collection Binding not found

What it means

ValueError raised during vector index creation when a Qdrant-backed dataset has a non-null collection_binding_id but the DatasetCollectionBinding row with that id does not exist in the database. The binding is required to derive the correct collection_name for Qdrant; its absence means the dataset points to a deleted binding.

Source

Thrown at api/commands/vector.py:222

                if dataset.index_struct_dict:
                    if dataset.index_struct_dict["type"] == vector_type:
                        skipped_count = skipped_count + 1
                        continue
                collection_name = ""
                dataset_id = dataset.id
                if vector_type in upper_collection_vector_types:
                    collection_name = Dataset.gen_collection_name_by_id(dataset_id)
                elif vector_type == VectorType.QDRANT:
                    if dataset.collection_binding_id:
                        dataset_collection_binding = db.session.execute(
                            select(DatasetCollectionBinding).where(
                                DatasetCollectionBinding.id == dataset.collection_binding_id
                            )
                        ).scalar_one_or_none()
                        if dataset_collection_binding:
                            collection_name = dataset_collection_binding.collection_name
                        else:
                            raise ValueError("Dataset Collection Binding not found")
                    else:
                        collection_name = Dataset.gen_collection_name_by_id(dataset_id)

                elif vector_type in lower_collection_vector_types:
                    collection_name = Dataset.gen_collection_name_by_id(dataset_id).lower()
                else:
                    raise ValueError(f"Vector store {vector_type} is not supported.")

                index_struct_dict = {"type": vector_type, "vector_store": {"class_prefix": collection_name}}
                dataset.index_struct = json.dumps(index_struct_dict)
                with Session(db.engine) as session:
                    vector = Vector(dataset, session=session)
                click.echo(f"Migrating dataset {dataset.id}.")

                try:
                    vector.delete()
                    click.echo(
                        click.style(f"Deleted vector index {collection_name} for dataset {dataset.id}.", fg="green")

View on GitHub (pinned to ef8544b173)

Solutions

  1. Query `SELECT id, collection_binding_id FROM datasets WHERE id='<dataset_id>';` then check the binding row exists.
  2. If orphaned, clear dataset.collection_binding_id so it falls back to gen_collection_name_by_id, or recreate the binding.
  3. Skip the dataset and re-run after repair, since the loop continues on per-dataset exceptions.
  4. Audit for other datasets referencing the missing binding.

Example fix

-- before
-- dataset.collection_binding_id='b1' but b1 row is gone -> raises

-- after - either clear the dangling reference
UPDATE datasets SET collection_binding_id=NULL WHERE id='<dataset_id>';
-- or recreate the binding row with the correct collection_name
Defensive patterns

Strategy: validation

Validate before calling

def binding_exists(session, binding_id: str | None) -> bool:
    if not binding_id:
        return True
    return session.scalar(
        select(func.count()).select_from(DatasetCollectionBinding)
        .where(DatasetCollectionBinding.id == binding_id)
    ) == 1

Type guard

def is_resolvable_binding(session, binding_id: str | None) -> bool:
    if not binding_id:
        return True
    return session.scalar(select(DatasetCollectionBinding).where(DatasetCollectionBinding.id == binding_id)) is not None

Try / catch

try:
    create_index_for_dataset(dataset)
except ValueError as exc:
    if "Dataset Collection Binding not found" in str(exc):
        click.echo(f"skip dataset={dataset.id} orphaned binding={dataset.collection_binding_id}", err=True)
        continue
    raise

Prevention

When it happens

Trigger: Triggered in the create-dataset-index migration loop when vector_type is QDRANT, dataset.collection_binding_id is set, and `select(DatasetCollectionBinding).where(id == collection_binding_id)` returns None.

Common situations: A DatasetCollectionBinding was deleted but the Dataset still references its id (orphaned FK), or the binding was never committed during a failed prior migration.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/5cd02bfa65da9dd8. Report an issue: GitHub.