question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Confusing error when path is omitted from a json filter

See original GitHub issue

Bug description

When the path field is omitted from a json filter the following error is returned:

Error occurred during query execution:
ConnectorError(ConnectorError { user_facing_error: None, kind: QueryError(Error { kind: Db, cause: Some(DbError { severity: "ERROR", parsed_severity: Some(Error), code: SqlState("42883"), message: "operator does not exist: jsonb ~~ unknown", detail: None, hint: Some("No operator matches the given name and argument types. You might need to add explicit type casts."), position: Some(Original(116)), where_: None, schema: None, table: None, column: None, datatype: None, constraint: None, file: Some("parse_oper.c"), line: Some(722), routine: Some("op_error") }) }) })

How to reproduce

Start the Query Engine with the datamodel provided below and execute the given GraphQL query.

Expected behavior

I would’ve expected an error message similar to the one provided when a field is missing from a createOne mutation, e.g.

Failed to validate the query: `Unable to match input value to any allowed input type for the field. Parse errors: [Query parsing/validation error at `Mutation.createOnePost.data.PostCreateInput.title`: A value is required but not set., Query parsing/validation error at `Mutation.createOnePost.data.PostUncheckedCreateInput.title`: A value is required but not set.]` at `Mutation.createOnePost.data`

Prisma information

datasource db {
  provider = "postgres"
  url      = env("DATABASE_URL")
}

generator db {
  provider             = "prisma-client-py"
  interface            = "asyncio"
  recursive_type_depth = -1
  previewFeatures      = ["filterJson"]
}

model Types {
  id       String @id @default(cuid())
  json_obj Json?  @default("{}")
}

GraphQL query:

query {
  result: findFirstTypes
  (
    where: {
      json_obj: {
        string_contains: "Rott"
      }
    }
  )
  {
    id
    json_obj
  }
}

Environment & setup

  • OS: Mac OS
  • Database: PostgreSQL
  • Node.js version: N/A

Prisma Version

prisma                : 3.4.0
@prisma/client        : Not found
Current platform      : darwin
Query Engine (Binary) : query-engine cc47a92cdfc3d0b9210fd4c86f33946a11e4636a (at ../../../../../var/folders/ql/0v8h20s972s6zz4t_3qc49bc0000gp/T/prisma/binaries/engines/cc47a92cdfc3d0b9210fd4c86f33946a11e4636a/prisma-query-engine-darwin, resolved by PRISMA_QUERY_ENGINE_BINARY)
Migration Engine      : migration-engine-cli cc47a92cdfc3d0b9210fd4c86f33946a11e4636a (at ../../../../../var/folders/ql/0v8h20s972s6zz4t_3qc49bc0000gp/T/prisma/binaries/engines/cc47a92cdfc3d0b9210fd4c86f33946a11e4636a/prisma-migration-engine-darwin, resolved by PRISMA_MIGRATION_ENGINE_BINARY)
Introspection Engine  : introspection-core cc47a92cdfc3d0b9210fd4c86f33946a11e4636a (at ../../../../../var/folders/ql/0v8h20s972s6zz4t_3qc49bc0000gp/T/prisma/binaries/engines/cc47a92cdfc3d0b9210fd4c86f33946a11e4636a/prisma-introspection-engine-darwin, resolved by PRISMA_INTROSPECTION_ENGINE_BINARY)
Format Binary         : prisma-fmt cc47a92cdfc3d0b9210fd4c86f33946a11e4636a (at ../../../../../var/folders/ql/0v8h20s972s6zz4t_3qc49bc0000gp/T/prisma/binaries/engines/cc47a92cdfc3d0b9210fd4c86f33946a11e4636a/prisma-prisma-fmt-darwin, resolved by PRISMA_FMT_BINARY)
Default Engines Hash  : 1c9fdaa9e2319b814822d6dbfd0a69e1fcc13a85
Studio                : 0.438.0

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
miguelffcommented, Nov 14, 2022

The script now just silently returns nothing, I’m not sure what the correct behaviour here is but I would’ve thought that omitting the path from the query would throw an error as AFAIK the filter cannot match anything when there is no path, but I could be wrong about that assumption.

So, json values can be anything JSON valid. This includes raw strings. If a path was always required, we wouldn’t be able to match strings at the root of the JSON blob. Check the following example:

import { PrismaClient } from '.prisma/client'

const prisma = new PrismaClient({
  log: ['query', 'info', 'warn'],
});

async function main() {

  await prisma.post.create({
    data: {
      meta: "Hello, world",
    }
  });

  const foo = await prisma.post.findFirst({
    where: {
      meta: {
        string_contains: "el",
      },
    },
  });
  console.log(foo);
}

main()
  .catch((e) => {
    throw e;
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
prisma:query BEGIN
prisma:query INSERT INTO "public"."Post" ("id","meta") VALUES ($1,$2) RETURNING "public"."Post"."id"
prisma:query SELECT "public"."Post"."id", "public"."Post"."meta" FROM "public"."Post" WHERE "public"."Post"."id" = $1 LIMIT $2 OFFSET $3
prisma:query COMMIT
prisma:query SELECT "public"."Post"."id", "public"."Post"."meta" FROM "public"."Post" WHERE ("public"."Post"."meta"::text LIKE $1 AND JSONB_TYPEOF("public"."Post"."meta") = $2) LIMIT $3 OFFSET $4
{ id: 'clagtie2b0000rbjyh5z96a7v', meta: 'hello world' }

For that reason I’m hesitant to consider this a bug, and unless there’s any objection, the existing behavior is correct, and the query should return null when the intent of the user is look into the JSON structure, but no field is provided in the query.

1reaction
pimeyscommented, Sep 9, 2022

The issue of no data and no error does exist in 4.3.1. Reproduction:

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model Post {
  id         String   @id @default(cuid())
  meta       Json     @default("{}")
}
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient({
  log: ['query', 'info', 'warn', 'error'],
})

async function main() {
  await prisma.post.deleteMany()

  await prisma.post.create({
    data: {
      meta: {
        field: "foobar",
      }
    }
  })

  const data = await prisma.post.findMany({
    where: {
      meta: {
        //path: ["field"], <- uncomment this to make it work
        string_contains: "foo",
      }
    }
  })

  console.log(data)
}

main()
  .then(async () => {
    await prisma.$disconnect()
  })
  .catch(async (e) => {
    console.error(e)
    await prisma.$disconnect()
    process.exit(1)
  })

Debug logs:

  prisma:tryLoadEnv  Environment variables loaded from /prisma-10103/.env +0ms
  prisma:tryLoadEnv  Environment variables loaded from /prisma-10103/.env +2ms
  prisma:client  dirname /prisma-10103/node_modules/.prisma/client +0ms
  prisma:client  relativePath ../../../prisma +0ms
  prisma:client  cwd /prisma-10103/prisma +0ms
  prisma:client  clientVersion 4.3.1 +0ms
  prisma:client  clientEngineType library +0ms
  prisma:client:libraryEngine  internalSetup +0ms
  prisma:client:libraryEngine:loader  Searching for Query Engine Library in /prisma-10103/node_modules/.prisma/client +0ms
  prisma:client:libraryEngine:loader  loadEngine using /prisma-10103/node_modules/.prisma/client/libquery_engine-debian-openssl-1.1.x.so.node +0ms
  prisma:client  Prisma Client call: +45ms
  prisma:client  prisma.post.deleteMany(undefined) +1ms
  prisma:client  Generated request: +0ms
  prisma:client  mutation {
  deleteManyPost {
    count
  }
}
 +0ms
  prisma:client:libraryEngine  sending request, this.libraryStarted: false +45ms
  prisma:client:libraryEngine  library starting +0ms
prisma:info Starting a postgresql pool with 33 connections.
  prisma:client:libraryEngine  library started +17ms
prisma:query BEGIN
prisma:query SELECT "public"."Post"."id" FROM "public"."Post" WHERE 1=1 OFFSET $1 /* traceparent=00-00-00-00 */
prisma:query SELECT "public"."Post"."id" FROM "public"."Post" WHERE 1=1 /* traceparent=00-00-00-00 */
prisma:query DELETE FROM "public"."Post" WHERE "public"."Post"."id" IN ($1) /* traceparent=00-00-00-00 */
prisma:query COMMIT
  prisma:client  Prisma Client call: +31ms
  prisma:client  prisma.post.create({
  data: {
    meta: {
      field: 'foobar'
    }
  }
}) +0ms
  prisma:client  Generated request: +0ms
  prisma:client  mutation {
  createOnePost(data: {
    meta: "{\"field\":\"foobar\"}"
  }) {
    id
    meta
  }
}
 +0ms
  prisma:client:libraryEngine  sending request, this.libraryStarted: true +15ms
prisma:query BEGIN
prisma:query INSERT INTO "public"."Post" ("id","meta") VALUES ($1,$2) RETURNING "public"."Post"."id" /* traceparent=00-00-00-00 */
prisma:query SELECT "public"."Post"."id", "public"."Post"."meta" FROM "public"."Post" WHERE "public"."Post"."id" = $1 LIMIT $2 OFFSET $3 /* traceparent=00-00-00-00 */
prisma:query COMMIT
  prisma:client  Prisma Client call: +4ms
  prisma:client  prisma.post.findMany({
  where: {
    meta: {
      string_contains: 'foo'
    }
  }
}) +1ms
  prisma:client  Generated request: +0ms
  prisma:client  query {
  findManyPost(where: {
    meta: {
      string_contains: "foo"
    }
  }) {
    id
    meta
  }
}
 +0ms
  prisma:client:libraryEngine  sending request, this.libraryStarted: true +4ms
prisma:query SELECT "public"."Post"."id", "public"."Post"."meta" FROM "public"."Post" WHERE ("public"."Post"."meta"::text LIKE $1 AND JSONB_TYPEOF("public"."Post"."meta") = $2) OFFSET $3 /* traceparent=00-00-00-00 */
[]
  prisma:client:libraryEngine  library stopping +6ms
  prisma:client:libraryEngine  library stopped +0ms
  prisma:client:libraryEngine:exitHooks  exit event received: beforeExit +0ms
  prisma:client:libraryEngine:exitHooks  exit event received: exit +0ms
Read more comments on GitHub >

github_iconTop Results From Across the Web

Karate json path filter not working when trying to extract ...
I am trying to filter my API response using JSON Path filter using ... not able to map variable properly, so my filter...
Read more >
Filtering | JSON:API module | Drupal Wiki guide on Drupal.org
First, a warning: don't make the mistake of confusing filters for access control. Just because you've written a filter to remove something that ......
Read more >
12.18.3 Functions That Search JSON Values
Returns data from a JSON document, selected from the parts of the document matched by the path arguments. Returns NULL if any argument...
Read more >
12: 9.15. JSON Functions and Operators - PostgreSQL
The field/element/path extraction operators return NULL, rather than failing, if the JSON input does not have the right structure to match the request;...
Read more >
13: 9.16. JSON Functions and Operators : Postgres Professional
Extracts JSON sub-object at the specified path, where path elements can be ... The jsonpath operators @? and @@ suppress the following errors:...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found