{"record":{"id":"a6f07cccefc79d32","repo":"pathwaycom/pathway","slug":"database-path-str-r-is-an-existing-directory-no","errorCode":null,"errorMessage":"database {path_str!r} is an existing directory, not a DuckDB database file. DuckDB cannot open a directory as a database; pass a file path instead.","messagePattern":"database (.+?) is an existing directory, not a DuckDB database file\\. DuckDB cannot open a directory as a database; pass a file path instead\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/duckdb/__init__.py","lineNumber":33,"sourceCode":"from pathway.internals.trace import trace_user_frame\nfrom pathway.io._utils import (\n    SNAPSHOT_OUTPUT_TABLE_TYPE,\n    get_column_index,\n    init_mode_from_str,\n)\n\nIN_MEMORY_DATABASE = \":memory:\"\n\n\ndef _reject_directory_path(path_str: str) -> None:\n    \"\"\"Reject a ``database`` path that resolves to an existing directory\n    (directly or via a symlink). Without this preflight DuckDB fails later\n    with an opaque \"unable to open database\" error inside an engine worker.\n    \"\"\"\n    if path_str == IN_MEMORY_DATABASE:\n        return\n    if os.path.isdir(path_str):\n        raise ValueError(\n            f\"database {path_str!r} is an existing directory, not a DuckDB \"\n            \"database file. DuckDB cannot open a directory as a database; \"\n            \"pass a file path instead.\"\n        )\n\n\n@check_arg_types\n@trace_user_frame\ndef write(\n    table: Table,\n    *,\n    table_name: str,\n    database: PathLike | str,\n    max_batch_size: int | None = None,\n    init_mode: Literal[\"default\", \"create_if_not_exists\", \"replace\"] = \"default\",\n    output_table_type: Literal[\"stream_of_changes\", \"snapshot\"] = \"stream_of_changes\",\n    primary_key: list[ColumnReference] | None = None,\n    detach_between_batches: bool = False,","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/duckdb/__init__.py#L15-L51","documentation":"Raised by pw.io.duckdb.write when the `database` argument resolves to an existing directory rather than a DuckDB database file. DuckDB cannot open a directory as a database; without this preflight check DuckDB would fail later inside an engine worker with an opaque 'unable to open database' error. The check is skipped for the special ':memory:' path.","triggerScenarios":"Calling pw.io.duckdb.write(table, table_name=..., database=<path>) where <path> is an existing directory, either directly or via a symlink. Common when a config var pointing at a data directory is passed unmodified, or when the intended filename was never appended to the directory path.","commonSituations":"Reusing a DATA_DIR environment variable as the database path without joining a filename; typos where the .duckdb extension and file name are omitted; build pipelines that pre-create output directories; symlinked paths that point at folders.","solutions":["Pass a full file path, e.g. os.path.join(data_dir, 'out.duckdb') instead of data_dir itself.","Check the value with os.path.isdir(...) before calling write() to fail fast in your own code with your own message.","If you intended an in-memory database, pass database=\":memory:\" exactly — that string is explicitly exempted.","Inspect the variable/symlink chain feeding `database` (os.path.realpath) to find where the directory crept in."],"exampleFix":"# before\npw.io.duckdb.write(t, table_name=\"t\", database=\"/data/warehouse\")\n\n# after\npw.io.duckdb.write(t, table_name=\"t\", database=\"/data/warehouse/out.duckdb\")","handlingStrategy":"validation","validationCode":"import os\n\n database = \"/data/warehouse/out.duckdb\"\n if database != \":memory:\" and os.path.isdir(database):\n    raise ValueError(f\"{database} is a directory; pass a database file path\")","typeGuard":"def is_duckdb_file_path(p: str) -> bool:\n    return p == \":memory:\" or (os.path.exists(p) and not os.path.isdir(p)) or not os.path.exists(p)","tryCatchPattern":"try:\n    pw.io.duckdb.write(t, table_name=\"t\", database=path)\nexcept ValueError as e:\n    if \"existing directory\" in str(e):\n        path = os.path.join(path, \"out.duckdb\")\n        pw.io.duckdb.write(t, table_name=\"t\", database=path)\n    else:\n        raise","preventionTips":["Never feed a DATA_DIR-style variable directly as `database`; always os.path.join(dir, filename).","Add an integration test that runs write() against a temp directory path with a real filename.","Document ':memory:' as the only non-file value allowed."],"tags":["duckdb","filesystem","connector","config"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}