{"record":{"id":"094f2ea7d08e7f14","repo":"pathwaycom/pathway","slug":"batch-size-must-be-a-positive-integer-got-batch-094f2e","errorCode":null,"errorMessage":"batch_size must be a positive integer, got {batch_size}.","messagePattern":"batch_size must be a positive integer, got (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/qdrant/__init__.py","lineNumber":138,"sourceCode":"    ...         (1, [0.1, 0.2, 0.3, 0.4], [(7, 2.0), (21, 1.0)], \"a\"),\n    ...         (2, [0.5, 0.6, 0.7, 0.8], [(3, 1.0)], \"b\"),\n    ...     ],\n    ... )\n    >>> pw.io.qdrant.write(   # doctest: +SKIP\n    ...     table,\n    ...     url=\"http://localhost:6334\",\n    ...     collection_name=\"docs\",\n    ... )\n    >>> pw.run(monitoring_level=pw.MonitoringLevel.NONE)  # doctest: +SKIP\n\n    If the collection declares only the dense ``embedding`` slot, drop the\n    ``bm25`` column from the schema above — this is the common non-hybrid\n    setup.\n    \"\"\"\n    _check_entitlements(\"qdrant\")\n\n    if batch_size < 1:\n        raise ValueError(f\"batch_size must be a positive integer, got {batch_size}.\")\n\n    data_storage = api.DataStorage(\n        storage_type=\"qdrant\",\n        qdrant_params=api.QdrantParams(\n            url=url,\n            collection_name=collection_name,\n            api_key=api_key,\n            batch_size=batch_size,\n        ),\n    )\n    data_format = api.DataFormat(\n        format_type=\"identity\",\n        key_field_names=[],\n        value_fields=_format_output_value_fields(table),\n    )\n\n    table.to(\n        datasink.GenericDataSink(","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/qdrant/__init__.py#L120-L156","documentation":"Raised by pw.io.qdrant.write when batch_size is less than 1. The value is forwarded to the Qdrant params and controls how many points are upserted per request; zero or negative batches are meaningless and would break the upsert loop or the server request, so it is validated up front.","triggerScenarios":"Calling pw.io.qdrant.write(t, url=..., collection_name=..., batch_size=0) or a negative value, typically from a config/env variable or a computed default that underflows.","commonSituations":"batch_size read from an environment variable that defaults to 0 when unset; tuning scripts sweeping batch sizes starting at 0; config files shared across tools where 0 means 'auto' elsewhere but is invalid here.","solutions":["Set batch_size to a positive integer (e.g. the default or something like 64-512 depending on payload size).","Validate config at load time: parse the value and assert it is >= 1 before wiring the sink.","Treat 0 as 'use default' explicitly if your config convention uses it: batch_size = cfg.batch or DEFAULT_BATCH."],"exampleFix":"# before\npw.io.qdrant.write(t, url=\"http://localhost:6334\", collection_name=\"docs\", batch_size=0)\n\n# after\npw.io.qdrant.write(t, url=\"http://localhost:6334\", collection_name=\"docs\", batch_size=128)","handlingStrategy":"validation","validationCode":"batch_size = int(os.environ.get(\"QDRANT_BATCH\", 128))\nassert batch_size >= 1, f\"batch_size must be >= 1, got {batch_size}\"\npw.io.qdrant.write(t, url=url, collection_name=col, batch_size=batch_size)","typeGuard":"def valid_batch_size(n) -> bool:\n    return isinstance(n, int) and n >= 1","tryCatchPattern":null,"preventionTips":["Never default batch sizes to 0; use a positive default like 128.","Validate numeric config at load time with a lower bound.","Treat 0-as-default conventions explicitly: cfg.batch or DEFAULT."],"tags":["pathway","qdrant","vector-db","configuration","validation"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}