Features work, but console delivers extraneous error: "Variable "$id" of required type "ID!" was not provided." - graphql

My CRUD operations work. But many of them also generate a single, specific console error I haven't been able to track down.
[GraphQL error]: Message: Variable "$id" of required type "ID!" was not provided., Location: [object Object], Path: undefined
Example: I can view a list of users without generating an error, and I can access the "details" view of a single user without generating an error. Those two work fine in isolation. But somehow, traversing from the former to the latter generates the error.
I tested both queries (users and user) in GraphQL-Playground, and did not receive errors. I also tried the IDs as type "String" rather than type "ID!". (Also without the !). I experimented with other "hacky" ways of feeding the user id to the resolver. And I've tried passing in other fields in lieu of the "info" argument in the query resolver.
To reiterate, Viewing either page in isolation (ie: clearing the console and reloading either page) does NOT trigger the error. It seems to be something about the journey from /users to user?id=12345.
from datamodel.prisma:
type User {
id: ID! #unique
createdAt: DateTime!
updatedAt: DateTime!
name: String!
email: String! #unique
password: String!
resetToken: String
resetTokenExpiry: Float
permissions: Permission
posts: [Post]! #relation(name: "PostsOfUser" onDelete: CASCADE)
comments: [Comment!]! #relation(name: "CommentsOfUser" onDelete:
CASCADE)
from query object in schema.graphql:
user(id: ID!): User
user query resolver:
async user(parent, { id }, { db, request }, info) {
const user = await db.query.user({ where: { id } }, info);
return user;
gql query using react-apollo and graphql-tag packages:
const SINGLE_USER_QUERY = gql`
query SINGLE_USER_QUERY($id: ID!){
user(id: $id) {
id
name
email
permissions
createdAt
updatedAt
}
}
`;
Expected behavior: User can click on a single user from a list of users, and the following page will contain details about that user.
Actual results: It works, but also generates console errors:
[GraphQL error]: Message: Variable "$id" of required type "ID!" was
not provided., Location: [object Object], Path: undefined
index.js:86
[Network error]: ServerError: Response not successful: Received status code 400
index.js:2178 GraphQL error occurred [getDataFromTree] Error:
Network error: Response not successful: Received status code 400
at new ApolloError (ApolloError.js:37)
at QueryManager.js:328
at QueryManager.js:700
at Array.forEach (<anonymous>)
at QueryManager.js:699
at Map.forEach (<anonymous>)
at QueryManager.push../node_modules/apollo-client/core/QueryManager.js.QueryManager.broadcastQueries (QueryManager.js:694)
at QueryManager.js:277

Please add an if condition for the parameter and check whether it is true. Then add a get(REST API) or query(GrahQL) function inside it. Then it won't show this error. Please see the below example
async user(parent, { id }, { db, request }, info) {
if ( id ) {
//enter your code
const user = await db.query.user({ where: { id } }, info);
return user;
}
}

Related

AWS AppSync GraphQL subscriptions returning null values on event

New to GraphQL, Amplify, AppSync, etc, and running into an issue when attempting to subscribe to an onUpdate event.
I added the 'API' library to my Amplify project with authentication through an API key. I can successfully send a mutation (updatePurchaseOrder) request through Postman, and the subscription listener registers an update, but the data returned is null on everything besides the id of the updated record.
screenshot in the AppSync console
The status field is null here, I would expect to see the new updated value. Is that the expected behavior?
The defined type on this:
type PurchaseOrder #model #auth(rules: [ { allow: public } ] ){
id: ID!
name: String!
description: String!
user: String
time: String
file: String!
status: String
}
Schema mutations and subscriptions created from the initial type definition haven't been changed:
type PurchaseOrder {
id: ID!
name: String!
description: String!
user: String
time: String
file: String!
status: String
createdAt: AWSDateTime!
updatedAt: AWSDateTime!
}
type Mutation {
updatePurchaseOrder(input: UpdatePurchaseOrderInput!, condition: ModelPurchaseOrderConditionInput): PurchaseOrder
}
input UpdatePurchaseOrderInput {
id: ID!
name: String
description: String
user: String
time: String
file: String
status: String
}
type Subscription {
onUpdatePurchaseOrder: PurchaseOrder
#aws_subscribe(mutations: ["updatePurchaseOrder"])
}
I tried logging to console in browser and see the same empty object returned. Figured listening through the AppSyncConsole would be less error prone, but I'm still seeing the same result.
Figured out where I went wrong... I needed to specify the response fields I wanted in the POST query (eg.:
mutation updatePurchaseOrder {
updatePurchaseOrder(input: {status: "Pending", id: "53a98236-7b64-428c-93ea-2fae5228c0ef"}) {
id
**status**
}
)
'status' was not in the query response parameters originally. The subscription response will only include fields that are part of the mutation response in the query itself.

How to resolve Inconsistent __typename error in Relay?

I just tried to implement the Relay in Frontend for this graphql tutorial, In that tutorial, they created graphql server to store URL(Link) bookmarks with the User who posted those URLs.
The relationship between the link and the users is:
Link belongs_to :user,
User has_many :links.
And I listed out all the Links with Users in Frontend, at the time I got the below error.
Warning: RelayResponseNormalizer: Invalid record 1. Expected __typename to be consistent, but the record was assigned conflicting types Link and User. The GraphQL server likely violated the globally unique id requirement by returning the same id for different objects
I'm not aware of how much it will impact the application. because I got the expected result from Frontend.
Frontend View of Query.
I read this relay official blog for this kind of error, but there is no example to know how exactly to resolve this. so can someone help to resolve this?
Relay Query
graphql`
query LinkListQuery {
allLinks {
id,
description,
url,
postedBy {
id,
name
}
}
}`
Schema:
input AUTH_PROVIDER_CREDENTIALS {
email: String!
password: String!
}
input AuthProviderSignupData {
credentials: AUTH_PROVIDER_CREDENTIALS
}
type Link implements Node {
description: String!
id: ID!
postedBy: User
url: String!
votes: [Vote!]!
}
input LinkFilter {
OR: [LinkFilter!]
descriptionContains: String
urlContains: String
}
type Mutation {
createLink(description: String!, url: String!): Link!
createUser(name: String!, authProvider: AuthProviderSignupData): User!
createVote(linkId: ID): Vote!
signinUser(credentials: AUTH_PROVIDER_CREDENTIALS): SignInUserPayload
}
"""An object with an ID."""
interface Node {
"""ID of the object."""
id: ID!
}
type Query {
allLinks(filter: LinkFilter, first: Int, skip: Int): [Link]!
"""Fetches an object given its ID."""
node(
"""ID of the object."""
id: ID!
): Node
}
"""Autogenerated return type of SignInUser"""
type SignInUserPayload {
token: String
user: User
}
type User implements Node {
email: String!
id: ID!
links: [Link!]!
name: String!
votes: [Vote!]!
}
type Vote {
id: ID!
link: Link!
user: User!
}

Hasura GraphQL Type Error Inconsistent Object

I'm trying to add the User object to my AuthPayload in Hasura Actions. I'm new to GraphQL and Hasura, not sure what I'm doing wrong. Here's the error I'm getting in the Hasura console.
Inconsistent object: validation for the given custom types failed
because the type "User" of the field "user" in the object type
"AuthPayload" is object type which isn't allowed.
Here is what I have...
Action definition
type Mutation {
login(
email: String!
password: String!
): AuthPayload
}
New types definition
type AuthPayload {
token: String
user: User
}
type User {
id: uuid!
email: String!
role: String!
}
The error message clearly indicates that fields in AuthPayload could not be of complex types (objects).
So the fix would be:
type AuthPayload {
token : String
user_id : uuid!
email: String!
role: String!
}
put all fields of type User inside AuthPayload.

Cannot query field 'password' on type 'User' graphql

I'm using graphql and prisma.
datamodel.prisma
type User {
id: ID! #id
createdAt: DateTime! #createdAt
updatedAt: DateTime! #updatedAt
email: String! #unique
password: String!
first_name: String
}
schema.graphql
scalar Date
type Query {
users: [User!]!
}
type User {
id: ID!
createdAt: Date!
updatedAt: Date!
email: String!
first_name: String
}
resolver
users: (parent, args, context) => {
return context.prisma.users();
}
I expected to get a user list, but received the error:
query
{
users {
email
}
}
error
"Cannot query field 'password' on type 'User'. (line 7, column 5):\n password\n ^"
UPDATE 1
Tried to use a fragment, but got the same:
{
users {
...userFields
}
}
fragment userFields on User {
email
}
I'd like to also add a scenario that can very easily cause this same issue that took me a while to debug and I'm sure others will encounter, because it took me quite some time to realize the issue was actually being caused in my FRONTEND code where I was defining my auth-related Mutations.
Set Up
Here's what that looked like while developing much of my application:
datamodel.prisma (I've omitted some fields for simplicity sake)
type User {
id: ID! #id
name: String!
email: String! #unique
password: String!
}
schema.graphql (just showing the signUp Mutation for simplicity)
type Mutation {
signUp(email: String!, password: String!, name: String!): User!
}
SignUp.js (where I access the signUp Mutation exposed in schema.graphql)
const SIGNUP_MUTATION = gql`
mutation SIGNUP_MUTATION(
$email: String!
$name: String!
$password: String!
) {
signUp(email: $email, name: $name, password: $password) {
id
email
name
password
}
}
`
Notice that I am returning id, email, name, and password - this was because I wanted to make sure everything was working in development.
Introducing the Cannot query field 'password' on type 'User' error
Once I began working on security and created a special User type in schema.graphql so that I could hide protected fields such as password, that's when I got this issue:
schema.graphql (notice that I am now not exposing the password field on this frontend-facing User type)
type Mutation {
signUp(email: String!, password: String!, name: String!): User!
}
type User {
id: ID!
name: String!
email: String!
}
Solution
Because of the nature of this error message, I spent most of my morning puzzling over my backend code. But it turned out that the error was actually being caused in SignUp.js, where I was RETURNING the password field.
The solution was to simply remove that line from the list of return fields like so:
const SIGNUP_MUTATION = gql`
mutation SIGNUP_MUTATION(
$email: String!
$name: String!
$password: String!
) {
signUp(email: $email, name: $name, password: $password) {
id
email
name
}
}
`
Key Lessons
So if you're experiencing this issue, please check ALL of your relevant mutations and make sure that you're not returning any fields that you have protected as I described here.
Be sure to also check your frontend code and make sure you aren't trying to return fields that you have now protected and are no longer exposing to the frontend.
I hope this is helpful and saves people some time!
... aaah Prisma ...
I don't know if interfaces, unions or input types are supported. Graphql docs
Prisma generates almost everything ... but defining password as required (as type for DBB generation) for datamodel should not block querying for a type subset or type defined on existing model without using all fields.
For me it's a bit missleading error message. It can be resolver related.
Try to match types in resolver, don't return direct prisma query (operates on model types), but map queried data (an array) to filter out password field/property (to be query type compatible). It's a security concern, too - passwords shouldn't be read from outside.
I've created custom query which return a fragment and seems the error gone.
Just run in your console(in prisma folder):
PRISMA_MANAGEMENT_API_SECRET=mysecret42 prisma deploy

GraphQL: Return a type with non-nullable id field as a query result

I have this type:
type Profile {
id: ID! #isUnique
email: String! #isUnique
...
}
And a query:
profile(email: String!):Profile
When I run the query with a user that doesn't exist, my underlying resolver returns null and I was expecting GraphQL to like this.
But, I get this error:
Cannot return null for non-nullable field Profile.id.
This happens because the query is expected to return a Profile and a Profile must have id field.
But, the query's return type is not non-nullable Profile!, it is Profile which would mean the query might return nothing.
How to fix this properly?
Try returning null in your profile query resolver. If you return something like an empty object, the Profile resolver will pick that up and attempt to return undefined as Profile.id, which as you noted is a schema error.
Try something like this:
const queryProfileResolver = (_, { email }) => {
// getProfileByEmail should return null if no match is found
return getProfileByEmail(email)
}
your graphQL response will then look something like this
{
data: {
profile: null
}
}
First of all you need to drop your data base and use
types.graphql as it is
type Profile {
id: ID! #isUnique
email: String! #isUnique
...
}
deploy it and error would be gone.
Main reason for happening this is you've already deployed data with not null thus it can't changed you need to drop our database, that's it

Resources