Skip to content

connect() silently discards unknown keywords, so a mis-routed option is indistinguishable from one that did not help #40

Description

@ChrisGVE

Versions

  • ydb-dbapi 0.1.22, ydb 3.31.1
  • ydb-sqlalchemy, SQLAlchemy 2.0.51
  • Python 3.12.9, macOS
  • Server: ydbplatform/local-ydb:26.1.1.22

What happens

connect() accepts any keyword it doesn't recognise and discards it. No error, no warning, no log line.

Where this bit me: a YDB client resolves the endpoint it's given into the cluster's own node list and connects to whatever comes back. Inside Docker that's the container's internal hostname, which doesn't resolve from the host:

InterfaceError: Resolved endpoints for database /local: DiscoveryResult
  <self_location: 1, endpoints [<Endpoint d7e126e4eca8:2136, location 1, ssl: False>]>

The documented lever for that is disable_discovery. Passed as a URL query parameter through SQLAlchemy — ydb://…/local?disable_discovery=true — it is silently ignored, and the error above comes back completely unchanged. There's nothing to distinguish "I set the option and it didn't help" from "the option never arrived", so I spent a while investigating the wrong layer.

It works when routed explicitly:

create_engine(url, connect_args={"driver_config_kwargs": {"disable_discovery": True}})

which is fine once you know, but the discovery of why the first form does nothing is all cost and no signal.

Why this matters beyond my case

Silently dropping unknown connect keywords means every typo is invisible, and every option a user believes they've set may not be set. ssl, credentials-related keywords, timeouts — same exposure. It's the kind of thing where the failure shows up as "the setting doesn't work" bug reports against options that are working fine and just never arrived.

Suggested fix

Raise ProgrammingError (or at minimum warn) on an unrecognised keyword in connect(). If some keywords genuinely need to pass through to a lower layer, an explicit allow-list plus an error for the rest would still be a large improvement over accepting everything.

Unrelated but same session, in case it's useful context: I ended up not using disable_discovery at all, and instead gave the container hostname: localhost with the port mapped 2136→2136 so the address it advertises is actually true from the host. That keeps the production discovery path exercised instead of switching it off for a test harness.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions