pathwaycom/pathway · error · ValueError

path {path_str!r} is an existing directory, not a SQLite dat

Error message

path {path_str!r} is an existing directory, not a SQLite database file. SQLite cannot open a directory as a database; pass a file path instead.

What it means

Raised by the Pathway SQLite connector's read/write preflight when the path argument resolves to an existing directory (directly or through a symlink). rusqlite cannot open a directory as a database; without this check it would fail much later with an opaque 'disk I/O error' or 'unable to open database file' that panics an engine worker, so Pathway rejects the path eagerly with an actionable message.

Source

Thrown at python/pathway/io/sqlite/__init__.py:34

from pathway.internals.trace import trace_user_frame
from pathway.io._utils import (
    SNAPSHOT_OUTPUT_TABLE_TYPE,
    get_column_index,
    init_mode_from_str,
    read_schema,
)


def _reject_directory_path(path_str: str) -> None:
    """Reject ``path`` that resolves to an existing directory (directly
    or via symlink). Without this preflight the underlying ``rusqlite``
    call returns the opaque ``disk I/O error`` (read) or ``unable to
    open database file`` (write) at flush time, panicking an engine
    worker. ``os.path.isdir`` follows symlinks, so this also catches a
    symlink-to-directory.
    """
    if os.path.isdir(path_str):
        raise ValueError(
            f"path {path_str!r} is an existing directory, not a SQLite "
            "database file. SQLite cannot open a directory as a database; "
            "pass a file path instead."
        )


@check_arg_types
@trace_user_frame
def read(
    path: PathLike | str,
    table_name: str,
    schema: type[Schema],
    *,
    autocommit_duration_ms: int | None = 1500,
    name: str | None = None,
    max_backlog_size: int | None = None,
    debug_data: Any = None,
) -> Table:

View on GitHub (pinned to fa2f74a464)

Solutions

  1. Pass the actual database file path, e.g. 'data/app.db' instead of 'data/'.
  2. Check the variable used for the filename: ensure it is non-empty and ends with the .db/.sqlite filename you expect.
  3. If path comes from user input, guard with os.path.isdir(path) and surface a clear configuration error before calling read/write.

Example fix

# before
pw.io.sqlite.read("data/", "users", schema=S)  # data/ is a directory

# after
pw.io.sqlite.read("data/app.db", "users", schema=S)
Defensive patterns

Strategy: validation

Validate before calling

import os
if os.path.isdir(path):
    raise ValueError(f"{path!r} is a directory; pass the .db file path")
pw.io.sqlite.read(path, "users", schema=S)

Type guard

def is_sqlite_file_path(p) -> bool:
    import os
    return not os.path.isdir(p)

Prevention

When it happens

Trigger: Passing a directory path to pw.io.sqlite.read/write, e.g. path='data/' or path='.'; passing a symlink that points to a directory; building the path with os.path.join where the filename component ended up empty (path equal to the directory itself).

Common situations: Trailing-slash or bare-directory arguments meant to mean 'the db in this folder'; path templates where the database filename variable is empty; symlinks in deployment directories that point at folders; confusing the SQLite file connector with directory-based formats like csv.

Related errors


AI-assisted analysis of pathwaycom/pathway@fa2f74a464 (2026-08-15). Data as JSON: /api/errors/ed0498cd002cc532. Report an issue: GitHub.