prisma icon indicating copy to clipboard operation
prisma copied to clipboard

The "client" engine and @prisma/adapter-mariadb causes error when querying the infomation_schema

Open yayugu opened this issue 3 months ago • 4 comments

Bug description

I've working on to migrate from the Rust engine to the "client" engine and the maria-db adapter. However, I found that causes following query cause an error. That query worked without any problems

Run SELECT TABLE_NAME from information_schema.TABLES throws the following error. Error: Cannot serialize value of type string as Bytes

Severity

🚨 Critical: Data loss, app crash, security issue

Reproduction

Cannot find the good base example of Prisma + MySQL

Expected vs. Actual Behavior

Expected: It should work as same as Rust based engine

Actual: Throws the error.

Frequency

Consistently reproducible

Does this occur in development or production?

Both development and production

Is this a regression?

Yes, it worked with the Rust engine

Workaround

Back to the Rust engine.

Prisma Schema & Queries

const tables = await prisma.$queryRawUnsafe(
    `SELECT TABLE_NAME from information_schema.TABLES`
  );

Prisma Config

N/A

Logs & Debug Info

...
prisma:getGenerators neededVersions {} +0ms
prisma:getGenerators {
  "generatorBinaryPaths": {}
} +0ms
prisma:client-generator-ts:wasm buildWasmFileMap with {
  "runtimeName": "client"
} +140ms
prisma:client-generator-ts:wasm Skipping component engine for runtime client +0ms
prisma:client-generator-ts:wasm Skipping component compiler for runtime client +0ms
prisma:cli:bin Execution time for executing "await cli.parse(commandArray)": 558.347089 ms +58ms
prisma:client prisma.$queryRaw(SELECT TABLE_NAME from information_schema.TABLES, []) +1322ms
prisma:client Prisma Client call: +0ms
prisma:client prisma.$queryRaw({
  query: "SELECT TABLE_NAME from information_schema.TABLES",
  parameters: {
    values: "[]",
    __prismaRawParameters__: true
  }
}) +1ms
prisma:client Generated request: +0ms
prisma:client {
  "action": "queryRaw",
  "query": {
    "arguments": {
      "query": "SELECT TABLE_NAME from information_schema.TABLES",
      "parameters": "[]"
    },
    "selection": {}
  }
}
 +0ms
prisma:client:clientEngine sending request +0ms
prisma:driver-adapter:mariadb [js::getCapabilities] MySQL version: 8.0.39 from '[\n  [\n    "8.0.39"\n  ]\n]' +1348ms
prisma:driver-adapter:mariadb [js::getCapabilities] Inferred capabilities: '{\n  "supportsRelationJoins": true\n}' +1ms
  vite:resolve 0.23ms @prisma/client/runtime/query_compiler_bg.mysql.mjs -> /home/yayugu/gendai-cms/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/query_compiler_bg.mysql.mjs +1s
  vite-node:client:native /home/yayugu/gendai-cms/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/query_compiler_bg.mysql.mjs +1s
  vite:resolve 0.10ms @prisma/client/runtime/query_compiler_bg.mysql.wasm-base64.mjs -> /home/yayugu/gendai-cms/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/query_compiler_bg.mysql.wasm-base64.mjs +1ms
  vite-node:client:native /home/yayugu/gendai-cms/node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/query_compiler_bg.mysql.wasm-base64.mjs +1ms
  vite-node:client:native buffer +4ms
prisma:client:clientEngine query plan created {
  "type": "query",
  "args": {
    "type": "rawSql",
    "sql": "SELECT TABLE_NAME from information_schema.TABLES",
    "args": [],
    "argTypes": []
  }
} +34ms
prisma:driver-adapter:mariadb [js::query_raw] '{\n' +
  '  "sql": "SELECT TABLE_NAME from information_schema.TABLES",\n' +
  '  "args": [],\n' +
  '  "argTypes": []\n' +
  '}' +26ms
prisma:client:request_handler {} +12ms
prisma:error Cannot serialize value of type string as Bytes

 Test Files  no tests
      Tests  no tests
   Start at  17:34:43
   Duration  1.54s (transform 101ms, setup 0ms, collect 0ms, tests 0ms, environment 0ms, prepare 0ms)


⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Error ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Error: Cannot serialize value of type string as Bytes
 ❯ $t ../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/client.js:71:25273
 ❯ ../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/client.js:71:24198
 ❯ ../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/client.js:71:24187
 ❯ e.Sc ../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/client.js:71:24178
 ❯ e.interpretNode ../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/client.js:71:31057
 ❯ process.processTicksAndRejections node:internal/process/task_queues:105:5
 ❯ e.run ../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/client.js:71:29729
 ❯ e.execute ../../node_modules/.pnpm/@[email protected][email protected][email protected][email protected]/node_modules/@prisma/client/runtime/client.js:71:41858

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { clientVersion: '6.17.1' }

Environment & Setup

  • OS: Ubuntu 24.04
  • Database: MySQL 8.0.39
  • Node.js version: v22.18.0

Prisma Version

6.17.1

yayugu avatar Oct 13 '25 08:10 yayugu

I'm not sure but there seems to be a relationship with the collation. I could see the same error when I changed the collation of a column to utf8mb4_0900_bin in order to make it case-sensitive. If I revert it to utf8mb4_unicode_ci that is the default collation of my table, SELECT-ing the column causes no errors anymore.

JJoriping avatar Oct 17 '25 15:10 JJoriping

I'm experiencing same issue, doing:

const tableNames = await prisma.$queryRaw<
      Array<{ TABLE_NAME: string }>
    >`SELECT TABLE_NAME
      from information_schema.TABLES
      WHERE TABLE_SCHEMA = 'test'
        AND TABLE_TYPE != 'VIEW';`;

leads to Error: Cannot serialize value of type string as Bytes.

Paclkage versions as frollow from my package.json:

"@prisma/adapter-mariadb": "^6.19.0",
 "@prisma/client": "^6.19.0",
"prisma": "^6.19.0",

I'm already using standard utf8mb4_unicode_ci collation but no luck.

EDIT: After additional checks, the TABLE_NAME field from information_schema.TABLES is of type utf8mb3_bin.

Querying another column on same table (for example ENGINE, which uses collation utf8mb3_general_ci) leads to no problem.

AnimaLupi avatar Nov 16 '25 14:11 AnimaLupi

Still present in 7.0.

rivatove avatar Nov 25 '25 14:11 rivatove

I can confirm that this issue also occurs in queries other than on information_schema. In my case it reproduces when the string column uses the utf8mb4_bin collation.

It also happens both with raw SQL ($queryRaw) and with typed SQL ($queryRawTyped).

This is blocking me from upgrading to Prisma v7, which requires using @prisma/adapter-mariadb.

prisma/schema.prisma

generator client {
  provider = "prisma-client"
  output   = "../src/generated/prisma"
  previewFeatures = ["typedSql"]
}

datasource db {
  provider = "mysql"
}

model User {
  id   Int    @id @default(autoincrement())
  name String
}

Migration (changed the collation from the auto-generated migration)

-- CreateTable
CREATE TABLE `User` (
    `id` INTEGER NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(191) NOT NULL,

    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

Query (for typed SQL) getUsers.sql

SELECT * FROM User;

Code

import { PrismaClient } from "./generated/prisma/client.js";
import { PrismaMariaDb } from "@prisma/adapter-mariadb";
import { getUsers } from "./generated/prisma/sql.js";

const prisma = new PrismaClient({
  adapter: new PrismaMariaDb({...}),
});

async function main() {
  await prisma.user.deleteMany();

  await prisma.user.create({
    data: {
      name: "test",
    },
  });
  // raw query
  // const users = await prisma.$queryRaw`SELECT * FROM User`;
  // typed query
  const users = await prisma.$queryRawTyped(getUsers());
  console.log(users);
}

await main();

Command

npx prisma migrate dev
npx prisma generate --sql
npx tsx src/index.ts

Error

Error: Cannot serialize value of type string as Bytes
    at serializeRawValue (.../@prisma/client-engine-runtime/src/interpreter/serialize-sql.ts:80:15)

Versions

  • @prisma/client: 7.1.0
  • @prisma/adapter-mariadb: 7.1.0
  • @prisma/instrumentation: 7.1.0
  • Database: MySQL 8.0.41 (official Docker image)

kyota-fujikura avatar Dec 09 '25 06:12 kyota-fujikura

In my case the root cause was the ->> JSON operator in raw queries. It seems to no longer work and throw the above error.

rivatove avatar Dec 12 '25 16:12 rivatove

In my case, I ran into this issue with a SQL function that returns JSON. For some reason, the MariaDB adapter treats this JSON as bytes in the mapColumnType function (https://github.com/prisma/prisma/blob/main/packages/adapter-mariadb/src/conversion.ts#L86-L88).

I'm not entirely sure how the mariadb-connector classifies JSON fields, but I noticed that, unlike BLOBs, which represent the Bytes type due to their binary flag, these fields actually have field.collation.charset = 'utf8'.

I created a local fork of the adapter and applied this change:

if (field["dataTypeFormat"] === "json") {
  return ColumnTypeEnum.Json;
} else if (field.flags.valueOf() & BINARY_FLAG) {
  // @ts-ignore -- collation has a charset property that is not present in the type definition
  if (field.collation.charset === "utf8") {
    return ColumnTypeEnum.Json;
  }
  return ColumnTypeEnum.Bytes;
} else {
  return ColumnTypeEnum.Text;
}

So far, I haven't encountered errors in any other raw queries. I doubt this is the definitive solution, but it works for now. Until there is a better way to solve this that doesn't involve changing the DB collations, this is the workaround I’ll be using.

mariann03 avatar Dec 15 '25 21:12 mariann03