{"record":{"id":"f56f0b2e8b47c6a7","repo":"tursodatabase/turso","slug":"autocommit-must-be-true-false-or-legacy","errorCode":null,"errorMessage":"autocommit must be True, False, or 'LEGACY'","messagePattern":"autocommit must be True, False, or 'LEGACY'","errorType":"exception","errorClass":"ProgrammingError","httpStatus":null,"severity":"error","filePath":"bindings/python/turso/lib.py","lineNumber":384,"sourceCode":"            raise _map_turso_exception(exc)\n\n    @property\n    def in_transaction(self) -> bool:\n        try:\n            return not self._conn.get_auto_commit()\n        except Exception as exc:  # noqa: BLE001\n            raise _map_turso_exception(exc)\n\n    # Provide autocommit property for sqlite3-like API (optional)\n    @property\n    def autocommit(self) -> object | bool:\n        return self._autocommit_mode\n\n    @autocommit.setter\n    def autocommit(self, val: object | bool) -> None:\n        # Accept True, False, or \"LEGACY\"\n        if val not in (True, False, \"LEGACY\"):\n            raise ProgrammingError(\"autocommit must be True, False, or 'LEGACY'\")\n        self._autocommit_mode = val\n        # If switching to False, ensure a transaction is open\n        if val is False:\n            self._ensure_transaction_open()\n        # If switching to True or LEGACY, nothing else to do immediately.\n\n    def close(self) -> None:\n        # In sqlite3: If autocommit is False, pending transaction is implicitly rolled back.\n        try:\n            if self._autocommit_mode is False and self.in_transaction:\n                try:\n                    self._exec_ddl_only(\"ROLLBACK\")\n                except Exception:\n                    # As sqlite3 does, ignore rollback failure on close\n                    pass\n            self._conn.close()\n        except Exception as exc:  # noqa: BLE001\n            raise _map_turso_exception(exc)","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/python/turso/lib.py#L366-L402","documentation":"The Connection.autocommit setter accepts exactly True, False, or the string \"LEGACY\" (case-sensitive), mirroring the stdlib sqlite3 autocommit attribute. Any other value raises ProgrammingError before any state changes. Note that 1 and 0 pass because they compare equal to True/False.","triggerScenarios":"`conn.autocommit = \"legacy\"` (wrong case), `conn.autocommit = None`, `conn.autocommit = 2`, `conn.autocommit = \"on\"/\"off\"` — typically when the mode comes from a config file, environment variable, or JSON/YAML value instead of a literal.","commonSituations":"Reading the mode from env/config where casing differs; config formats that turn booleans into strings (\"true\"/\"false\"); porting isolation_level-style strings (\"DEFERRED\" etc.) to the autocommit attribute.","solutions":["Normalize the incoming value before assigning: map \"true\"/\"1\" to True, \"false\"/\"0\" to False, \"legacy\" (any case) to \"LEGACY\"","Assign literals directly at the call site: conn.autocommit = True / False / \"LEGACY\"","Treat any other value as a configuration error and fail fast with the raw value in the message"],"exampleFix":"# before\nconn.autocommit = os.environ.get(\"AUTOCOMMIT\", \"LEGACY\")  # \"legacy\" -> ProgrammingError\n\n# after\nmodes = {\"true\": True, \"false\": False, \"legacy\": \"LEGACY\"}\nraw = os.environ.get(\"AUTOCOMMIT\", \"LEGACY\").lower()\nif raw not in modes:\n    raise ValueError(f\"invalid AUTOCOMMIT={raw!r}; use true/false/legacy\")\nconn.autocommit = modes[raw]","handlingStrategy":"validation","validationCode":"_MODES = {\"true\": True, \"false\": False, \"legacy\": \"LEGACY\"}\n\ndef normalize_autocommit(raw) -> object | bool:\n    if raw is True or raw is False or raw == \"LEGACY\":\n        return raw\n    key = str(raw).strip().lower()\n    if key in _MODES:\n        return _MODES[key]\n    raise ValueError(f\"invalid autocommit value {raw!r}; use True/False/'LEGACY'\")\n\nconn.autocommit = normalize_autocommit(config[\"autocommit\"])","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use literals True/False/\"LEGACY\" (exact case) in code","Normalize any config/env-sourced value through one helper before assignment","Watch for config formats that coerce booleans to strings — \"true\" is not True"],"tags":["python","autocommit","transaction","validation","configuration"],"backgroundTag":"invalid-autocommit-mode","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}