{"record":{"id":"ce3455c233eb766b","repo":"phalcon/cphalcon","slug":"cannot-prepare-statement","errorCode":null,"errorMessage":"Cannot prepare statement","messagePattern":"Cannot prepare statement","errorType":"exception","errorClass":"Phalcon\\Db\\Exceptions\\CannotPrepareStatement","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Adapter/Pdo/AbstractPdo.zep","lineNumber":1000,"sourceCode":"\n        let eventsManager = <ManagerInterface> this->eventsManager;\n        if typeof eventsManager == \"object\" {\n            eventsManager->fire(\"db:connectionLost\", this);\n        }\n\n        this->connect();\n    }\n\n    /**\n     * Prepares and executes a read statement, returning the live PDOStatement.\n     */\n    private function queryStatement(string sqlStatement, array params, array types) -> <\\PDOStatement>\n    {\n        var statement;\n\n        let statement = this->pdo->prepare(sqlStatement);\n        if unlikely typeof statement != \"object\" {\n            throw new CannotPrepareStatement();\n        }\n\n        return this->executePrepared(statement, params, types);\n    }\n}\n","sourceCodeStart":982,"sourceCodeEnd":1006,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Adapter/Pdo/AbstractPdo.zep#L982-L1006","documentation":"queryStatement() — the private path behind query() — calls PDO::prepare() and throws CannotPrepareStatement if the result is not an object. When PDO runs with the default silent error mode (PDO::ERRMODE_SILENT), prepare() returns false on unpreparable SQL (syntax error, unknown column/driver limitation) instead of raising a PDOException, and this guard converts that false into an exception. With PDO::ERRMODE_EXCEPTION configured, PDO itself throws the more informative PDOException first, so seeing CannotPrepareStatement usually means error mode was silent.","triggerScenarios":"$connection->query($malformedSql) with a syntax error while PDO::ATTR_ERRMODE is not ERRMODE_EXCEPTION; statements the driver cannot prepare in the configured emulation mode; placeholder syntax mistakes (e.g. mixing ? and :name: or stray colons) making the statement unpreparable.","commonSituations":"Adapters created without options['PDO::ATTR_ERRMODE'] = PDO::ERRMODE_EXCEPTION; dynamically assembled SQL with a missing closing quote or bad JOIN clause; switching PDO::ATTR_EMULATE_PREPARES off/on exposing statements the server refuses to prepare; the generic message forcing developers to find the SQL bug without a driver error text.","solutions":["Set PDO exception mode in the adapter descriptor so failures carry the real driver message: options => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]","Log and inspect the exact SQL passed to query() — the exception carries no driver details by itself","Fix the SQL: check quoting, placeholder style, table/column names; run the statement manually in a DB client to compare"],"exampleFix":"// before\n$db = new Mysql(['host' => $h, 'username' => $u, 'password' => $p, 'dbname' => $d]);\n$db->query('SELECT FROM users WHERE id = 1'); // CannotPrepareStatement, no detail\n\n// after\n$db = new Mysql([\n    'host' => $h, 'username' => $u, 'password' => $p, 'dbname' => $d,\n    'options' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],\n]);\n$db->query('SELECT * FROM users WHERE id = 1'); // PDOException with real syntax error","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"use Phalcon\\Db\\Exceptions\\CannotPrepareStatement;\n\ntry {\n    $result = $connection->query($sql, $params, $types);\n} catch (CannotPrepareStatement $e) {\n    // error mode was silent: surface driver details from errorInfo()\n    $info = $connection->getErrorInfo();\n    throw new RuntimeException(sprintf(\n        'Query failed (%s): %s -- SQL: %s',\n        $info[0] ?? '?', $info[2] ?? $e->getMessage(), $sql\n    ), 0, $e);\n}","preventionTips":["Always create adapters with options => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] so prepare failures throw PDOException with the real driver message","Log the exact SQL string on failure — CannotPrepareStatement itself carries no SQL context","Test dynamic SQL against the real server (or a compatible test container) before shipping query builders"],"tags":["php","phalcon","db","pdo","sql","prepare","error-mode"],"backgroundTag":"sql-prepare-failed","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}