This document records verified bugs, misleading examples, or common pitfalls encountered while running real-world test code against the sqlx skill's md files. Every issue was confirmed with actual code execution before being added.
references/database-specifics.md— MySQL INSERT and Auto-Increment section
let id: i64 = sqlx::query_scalar("SELECT LAST_INSERT_ID()")
.fetch_one(&pool)
.await?;Error: ColumnDecode { index: "0", source: "mismatched types; Rust type `i64` (as SQL type `BIGINT`) is not compatible with SQL type `BIGINT UNSIGNED`" }
MySQL's LAST_INSERT_ID() returns a BIGINT UNSIGNED. sqlx maps unsigned MySQL integers to u64, not i64.
let id: u64 = sqlx::query_scalar("SELECT LAST_INSERT_ID()")
.fetch_one(&pool)
.await?;Additionally, LAST_INSERT_ID() is connection-specific. If using a pool, you must execute the INSERT and the LAST_INSERT_ID() query on the same acquired connection:
let mut conn = pool.acquire().await?;
sqlx::query("INSERT INTO users (name) VALUES (?)")
.bind("Alice")
.execute(&mut *conn)
.await?;
let id: u64 = sqlx::query_scalar("SELECT LAST_INSERT_ID()")
.fetch_one(&mut *conn)
.await?;references/type-mapping.md— Transparent Wrapper and Enum Mapping sections
#[derive(Debug, sqlx::Type, sqlx::Encode, sqlx::Decode)]
#[sqlx(type_name = "user_role", rename_all = "lowercase")]
enum UserRole {
Admin,
User,
Guest,
}error[E0119]: conflicting implementations of trait `sqlx::Encode<'_, _>` for type `UserRole`
The sqlx::Type derive macro already generates Encode and Decode implementations (as well as sqlx::Encode / sqlx::Decode trait derivations). Explicitly adding sqlx::Encode and sqlx::Decode as separate derive macro arguments creates duplicate/conflicting impls.
Use only #[derive(sqlx::Type)] for enums and structs with #[sqlx(transparent)]:
#[derive(Debug, sqlx::Type)]
#[sqlx(type_name = "user_role", rename_all = "lowercase")]
enum UserRole { Admin, User, Guest }
#[derive(Debug, sqlx::Type)]
#[sqlx(transparent)]
struct Email(String);Issue 3: cargo sqlx prepare — relative paths in migrate!() macro are NOT supported with paths relative to the current file's directory
references/transactions-migrations.md— Embedding Migrations in Codereferences/transactions-migrations.md—#[sqlx::test]With Migrations
let migrator = sqlx::migrate!("migrations/");error: paths relative to the current file's directory are not currently supported
The migrate!() macro requires the migration path to be relative to the crate root (the directory containing Cargo.toml), not the current source file's directory.
Pass the path relative to the crate root:
let migrator = sqlx::migrate!("./migrations");Note: The trailing slash is optional, but a leading ./ is recommended for crate-relative resolution.
references/database-specifics.md— PostgreSQL COPY (Bulk Import)
let mut writer = pool.copy_in_raw("...").await?;
writer.send(b"1,Alice,alice@example.com\n").await?;error[E0271]: type mismatch resolving `<&[u8; 26] as Deref>::Target == [u8]`
Byte string literals (b"...") have type &[u8; N], which does not implement Deref<Target = [u8]> directly in the context send() expects. You must cast to a slice.
writer.send(b"1,Alice,alice@example.com\n" as &[u8]).await?;Alternatively, use a Vec<u8> or string converted to bytes.
references/compile-time-checking.md—query_scalar!sectionreferences/testing-mocking.md— With Fixtures section
let count: i64 = sqlx::query_scalar!("SELECT COUNT(*) FROM users")
.fetch_one(&pool)
.await?;error[E0308]: `?` operator has incompatible types
expected `i64`, found `Option<i64>`
The compile-time macros infer the return type based on the database metadata. For aggregate functions like COUNT(*), some PostgreSQL versions may infer the result as nullable (Option<i64>). This is especially common with PostgreSQL.
Either use Option<i64> as the type, or use a type override with COUNT(*)::BIGINT:
let count: i64 = sqlx::query_scalar!("SELECT COUNT(*)::BIGINT FROM users")
.fetch_one(&pool)
.await?;Or accept Option:
let count: Option<i64> = sqlx::query_scalar!("SELECT COUNT(*) FROM users")
.fetch_one(&pool)
.await?;references/testing-mocking.md— With Migrations section
#[sqlx::test(migrations = "migrations/")]
async fn test_with_schema(pool: PgPool) -> sqlx::Result<()> { ... }error: paths relative to the current file's directory are not currently supported
Same as Issue 3 — the migrate!() macro (internally used by #[sqlx::test]) requires paths relative to the crate root, not the test file's directory.
Use a crate-root-relative path, or (safer) don't specify migrations if your schema is already present in the test DB. If migrations are needed, place them at the crate root and use:
#[sqlx::test(migrations = "./migrations")]
async fn test_with_schema(pool: PgPool) -> sqlx::Result<()> { ... }Alternatively, create tables inline in the test without relying on migrations for compile-time checked macros.
Issue 7: chrono needs serde feature for #[derive(Serialize, Deserialize)] on structs containing DateTime<Utc>
references/compile-time-checking.md—query!()examples withchrono::DateTime<chrono::Utc>
The skill frequently shows structs with chrono::DateTime<chrono::Utc> and #[derive(Serialize, Deserialize)], but does not mention that chrono must be configured with the serde feature:
chrono = { version = "0.4", features = ["serde"] }error[E0277]: the trait bound `DateTime<Utc>: serde::Serialize` is not satisfied
error[E0277]: the trait bound `DateTime<Utc>: serde::Deserialize<'_>` is not satisfied
Add the serde feature to chrono in Cargo.toml:
chrono = { version = "0.4", features = ["serde"] }references/database-specifics.md— UUID Type section
The skill shows Uuid::new_v4() but does not mention that the uuid crate must have the v4 feature enabled.
error[E0599]: no function or associated item named `new_v4` found for struct `Uuid`
uuid = { version = "1", features = ["v4"] }references/database-specifics.md— Network Types sectionreferences/type-mapping.md— Network Types
The skill says ipnet::IpNet requires the ipnet feature on sqlx, but in practice the ipnet crate must also be added as an explicit dependency because the Rust code directly uses ipnet::IpNet.
error[E0433]: cannot find module or crate `ipnet` in this scope
Add ipnet as a direct dependency in addition to enabling the sqlx feature:
[dependencies]
sqlx = { version = "0.8", features = ["ipnet", "postgres", ...] }
ipnet = "2"| # | Issue | Skill File | Severity |
|---|---|---|---|
| 1 | MySQL LAST_INSERT_ID() type is u64, not i64 |
database-specifics.md |
High |
| 2 | sqlx::Type already includes Encode/Decode |
type-mapping.md |
High |
| 3 | migrate!("...") paths must be crate-root-relative |
transactions-migrations.md |
Medium |
| 4 | PgCopyIn::send() needs as &[u8] cast |
database-specifics.md |
Medium |
| 5 | COUNT(*) may infer to Option<i64> in query_scalar! |
compile-time-checking.md |
Medium |
| 6 | #[sqlx::test(migrations = ...)] needs crate-relative path |
testing-mocking.md |
Medium |
| 7 | chrono needs serde feature for struct derives |
compile-time-checking.md |
Low |
| 8 | uuid needs v4 feature for new_v4() |
database-specifics.md |
Low |
| 9 | ipnet needs explicit dependency in Cargo.toml |
type-mapping.md |
Low |