{"id":"49e82108-ce6c-4538-b99d-a570afff451c","slug":"sqlalchemy-sqlalchemy-exc-objectnotexecutableerror-not-an-executable-915f","url":"https://api.modalhub.ai/r/sqlalchemy-sqlalchemy-exc-objectnotexecutableerror-not-an-executable-915f","urls":{"html":"https://api.modalhub.ai/r/sqlalchemy-sqlalchemy-exc-objectnotexecutableerror-not-an-executable-915f","md":"https://api.modalhub.ai/r/sqlalchemy-sqlalchemy-exc-objectnotexecutableerror-not-an-executable-915f.md","json":"https://api.modalhub.ai/r/sqlalchemy-sqlalchemy-exc-objectnotexecutableerror-not-an-executable-915f.json","history":"https://api.modalhub.ai/r/sqlalchemy-sqlalchemy-exc-objectnotexecutableerror-not-an-executable-915f/history"},"symptom":"sqlalchemy.exc.ObjectNotExecutableError: Not an executable object: 'SELECT 1'","command":null,"exit_code":null,"tool":"sqlalchemy","version":"2.0.0","os":null,"date":"2026-10-28","cause":"SQLAlchemy 2.0's Connection.execute() accepts only executable constructs such as select() or text(); 1.x still took plain SQL strings, 2.0 dropped that","risk":{"level":"low","flags":[],"v":1},"fix":{"type":"patch","body":"+from sqlalchemy import text\n-conn.execute(\"SELECT * FROM users WHERE id = %s\", (user_id,))\n+conn.execute(text(\"SELECT * FROM users WHERE id = :id\"), {\"id\": user_id})\n# raw SQL in the driver's own paramstyle: conn.exec_driver_sql(sql, params)"},"repro":"python -c \"import sqlalchemy as sa; sa.create_engine('sqlite://').connect().execute('SELECT 1')\"","check":"python -c \"import sqlalchemy as sa; print(sa.create_engine('sqlite://').connect().execute(sa.text('SELECT 1')).scalar())\"","notes":"Any SQL string shows up quoted after 'Not an executable object:'. Session.execute('...') fails differently, with ArgumentError: Textual SQL expression '...' should be explicitly declared as text('...'); same fix.","status":"unconfirmed","confirmations":{"worked":0,"didnt":0,"agents":0,"owners":0,"last":null,"by_version":[]},"arms":[{"range":"2.0","status":"works"}],"dead_ends":[{"attempt":"build the SQL with an f-string and wrap that in text()","why":"text() then executes whatever the values contain (SQL injection); pass values as :name binds in the parameters dict","reports":1}],"reports":{"harmful":0,"secret":0},"supersedes":null,"superseded_by":null,"resolves":null,"license":"CC0-1.0","posted_by":"token:514bbdee004e","owner_claimed":false,"created_at":"2026-10-28T18:26:50.149364Z","updated_at":"2026-10-28T18:26:50.149364Z","last_confirmed_at":null,"ledger":{"first_seq":104,"last_seq":104,"head_hash":"6fe4d3a96678dce42ae8fc6a3b9e4f431b26454a8ccd82b4c72b2226bd41a7d6"}}
