{"record":{"id":"25ca270524bec0fb","repo":"tursodatabase/turso","slug":"tursosyncdialect-does-not-support-host-port-in-url","errorCode":null,"errorMessage":"TursoSyncDialect does not support host/port in URL. The local database path goes after ':///', and remote_url is specified as a query parameter.","messagePattern":"TursoSyncDialect does not support host/port in URL\\. The local database path goes after ':///', and remote_url is specified as a query parameter\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"bindings/python/turso/sqlalchemy/dialect.py","lineNumber":386,"sourceCode":"        return turso.sync\n\n    def connect(self, *cargs, **cparams):\n        \"\"\"Remap sync_url to remote_url for libsql-sqlalchemy compatibility.\"\"\"\n\n        if \"sync_url\" in cparams and \"remote_url\" not in cparams:\n            cparams[\"remote_url\"] = cparams.pop(\"sync_url\")\n        return super().connect(*cargs, **cparams)\n\n    @staticmethod\n    def _validate_sync_url(opts: Dict[str, Any]) -> None:\n        \"\"\"Reject URL components that TursoSyncDialect doesn't support.\"\"\"\n        if opts.get(\"username\") or opts.get(\"password\"):\n            raise ValueError(\n                \"TursoSyncDialect does not support username/password in URL. \"\n                \"Use auth_token query parameter or connect_args instead.\"\n            )\n        if opts.get(\"host\") or opts.get(\"port\"):\n            raise ValueError(\n                \"TursoSyncDialect does not support host/port in URL. \"\n                \"The local database path goes after ':///', and remote_url \"\n                \"is specified as a query parameter.\"\n            )\n\n    @staticmethod\n    def _extract_sync_params(query_params: Dict[str, str]) -> Dict[str, Any]:\n        \"\"\"Extract and convert sync-specific query parameters into kwargs.\"\"\"\n        kwargs: Dict[str, Any] = {}\n\n        auth_token = query_params.pop(\"auth_token\", None)\n        if auth_token:\n            kwargs[\"auth_token\"] = auth_token\n\n        client_name = query_params.pop(\"client_name\", None)\n        kwargs[\"client_name\"] = client_name or \"turso-sqlalchemy\"\n\n        long_poll_timeout_ms = query_params.pop(\"long_poll_timeout_ms\", None)","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/python/turso/sqlalchemy/dialect.py#L368-L404","documentation":"Same validator (_validate_sync_url), second rule: a sqlite+turso_sync URL must be host-less. The local database file path goes after ':///' and the remote endpoint is supplied as a remote_url query parameter (or connect_args). Presence of host or port means the URL was built like a client-server DSN, which the sync dialect does not support.","triggerScenarios":"`create_engine(\"sqlite+turso_sync://db.example.com:443/local.db\")` or `sqlite+turso_sync://localhost/db` — treating the dialect like a network driver. Validation runs when the engine first builds connect args.","commonSituations":"Converting an existing libsql:// or postgres:// connection string by only swapping the scheme; templates that always emit //host/path; developers expecting the sync dialect to connect straight to the remote database.","solutions":["Use the host-less form with query parameters: `sqlite+turso_sync:///local.db?remote_url=libsql://db.example.com&auth_token=...`","Or keep the URL minimal and pass remote_url via connect_args","Remember the path component is a local file path, not a remote database name"],"exampleFix":"# before\nengine = create_engine(\"sqlite+turso_sync://db.example.com:443/local.db\")\n\n# after\nengine = create_engine(\"sqlite+turso_sync:///local.db?remote_url=libsql://db.example.com\")","handlingStrategy":"validation","validationCode":"from sqlalchemy.engine import make_url\n\ndef lint_turso_sync_url(url: str) -> str:\n    u = make_url(url)\n    if u.host or u.port:\n        raise ValueError(\n            \"sqlite+turso_sync URLs must be host-less: local path after ':///', \"\n            \"remote endpoint via remote_url query parameter\"\n        )\n    return url","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Memorize the shape: sqlite+turso_sync:///local.db?remote_url=<endpoint>","The path component is a local file path, not a remote database name","When converting libsql:// or postgres:// strings, strip host/port — do not just swap the scheme"],"tags":["python","sqlalchemy","connection-url","dsn","sync"],"backgroundTag":"invalid-connection-url","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}