Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot get error message from safeParse #2883

Closed
Creative-Difficulty opened this issue Oct 19, 2023 · 23 comments
Closed

Cannot get error message from safeParse #2883

Creative-Difficulty opened this issue Oct 19, 2023 · 23 comments

Comments

@Creative-Difficulty
Copy link

This should work:

//or process.env
const parsedEnv = envSchema.safeParse(Bun.env);
//@ts-ignore
if(parsedEnv.success === false) { console.error(parsedEnv.error.message); process.exit(1); }

but it doesn't.
Instead i have to do these shenanigans:

const parsedEnv = envSchema.safeParse(Bun.env);
if(parsedEnv.success === false) { console.error(JSON.parse(parsedEnv.error.message)[0].message); process.exit(1); }
@Creative-Difficulty
Copy link
Author

@colinhacks pls fix

@amany9000
Copy link

amany9000 commented Oct 22, 2023

@colinhacks @Creative-Difficulty, I'm facing the same issue and the return type for safeParse() is also incorrect.

@Creative-Difficulty
Copy link
Author

@amany9000 There's a quite easy workaround

@blackram
Copy link

blackram commented Dec 4, 2023

import { z } from 'zod'

const check = (env) => {
    const parsedEnv = z.string().safeParse(env);

    if(parsedEnv.success === false) { 
        console.error(parsedEnv.error.message); 
        process.exit(1); 
    } else {
        console.log('success!')
    }
}
check('1')
check(1)

when run

% node zod-repro.mjs

success!
[
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "number",
    "path": [],
    "message": "Expected string, received number"
  }
]

with: zod@^3.22.4

The issue is resolved already?

@Creative-Difficulty
Copy link
Author

No it isn't

@cloudbring
Copy link

cloudbring commented Dec 21, 2023

I'm seeing the same issue. Here's my code where I'm seeing it. I changed the variable names for security reasons but, it doesn't change anything.

const envSchema = z.object({
  NODE_ENV: z.string().default("development"),

  // FOO
  FOO_API_KEY: z.string(),

  // BAR
  BAR_KEY: z.string(),
  BAR_REGION: z.string(),
})

const parsed = envSchema.safeParse(process.env)

if (!parsed.success) {
  console.error(
    `Error #%d: Failed Parsing .env file.
    Please ensure that it exists and is valid: `,
    JSON.stringify(parsed.error.format(), null, 4)
    //                    ^^^^^
  );
  process.exit(1);
} else {
 ...
}

VSCode Error for the underlined object:

Property 'error' does not exist on type 'SafeParseReturnType<{ NODE_ENV?: string; FOO_API_KEY?: string; BAR_KEY?: string; BAR_REGION?: string; }, { NODE_ENV?: string; FOO_API_KEY?: string; BAR_KEY?: string; BAR_REGION?: string; }>'.
Property 'error' does not exist on type 'SafeParseSuccess<{ NODE_ENV?: string; FOO_API_KEY?: string; BAR_KEY?: string; BAR_REGION?: string; }>'.ts(2339)

@Creative-Difficulty Creative-Difficulty closed this as not planned Won't fix, can't repro, duplicate, stale Jan 3, 2024
@jeremydaly
Copy link

Do you have strict: true set in your tsconfig.json? I was getting this error when I had it set to false.

@Creative-Difficulty
Copy link
Author

This has nothing to do with strict mode.

@impuLssse
Copy link

I have same problem,
image
image

@Creative-Difficulty
Copy link
Author

This is still an issue

@nbolton
Copy link

nbolton commented Feb 15, 2024

Same here.
image

Workaround:
console.error((parsedObject as { error: Error }).error);

@GrahamS-Quartech
Copy link

This is still an issue in 2024. Considering the above works, it seems that it's just the type definitions that are broken.

@Eiley2
Copy link

Eiley2 commented Mar 24, 2024

Same, currenty facing this issue

@Shisuki
Copy link

Shisuki commented Mar 28, 2024

This is no longer an issue if you don't use deconstruction

In here parsingResult.error is defined but weirdly it's not defined when you try to deconstruct it.

image

@sir-captainmorgan21
Copy link

sir-captainmorgan21 commented Mar 30, 2024

It works if you do result.success === false. But !result.success doesn't work...

@vjlkof
Copy link

vjlkof commented Apr 20, 2024

Thanks for the solution my friend

@colinhacks
Copy link
Owner

You need to enable strictNullChecks: true or strict: true. Once enabled you will not see this error. This is a requirement for Zod to properly type the results of parsing.

@Pinky030
Copy link

Pinky030 commented May 3, 2024

I am still encountering this error. I have set strict: true in my tsconfig.json.

Tried result.success === false as a workaround solution but the build is still failing and returns an error message from safeParse

@Pinky030
Copy link

Pinky030 commented May 3, 2024

I am still encountering this error. I have set strict: true in my tsconfig.json.

Tried result.success === false as a workaround solution but the build is still failing and returns an error message from safeParse

It works when:

    if(result.success) { 
        const {data} = result;
        return data
    } 

@Downster
Copy link

Downster commented May 20, 2024

So I believe this issue is still present and may have been misunderstood. I am not having any issues with the types, however the return type for parsed.error.message is wrong. It says I should receive a string, but I actually receive an array with one error object inside of it, like so:

[
  {
    "code": "invalid_type",
    "expected": "string",
    "received": "number",
    "path": [],
    "message": "Expected string, received number"
  }
]

So, if you follow the documentation and provide parsed.error.message to the frontend, the frontend will show a JSON object. My current workaround is a function that grabs the error message and overrides the types like so:

export function getZodErrorMessage(error: z.ZodError): string {
  const message = error.message;
  const parsedMessage = JSON.parse(message) as Array<{ message: string }>;
  const zodError = parsedMessage[0];
  if (!zodError) throw Error("Zod is broken");
  return zodError.message;
}

However, I don't think this should be necessary. It would be nice if this was fixed at some point in the future! Thanks 😄

@aaronhipple
Copy link

So I believe this issue is still present and may have been misunderstood. I am not having any issues with the types, however the return type for parsed.error.message is wrong. [...]

Per today's code I think the type is actually technically correct (the best kind of correct):

zod/src/ZodError.ts

Lines 286 to 288 in f7ad261

override get message() {
return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
}

i.e. the output of the message getter is indeed a string, but a string of JSON rather than a human-readable message (as one might expect given the field's name).

I've opened #3937 to start a discussion about possible resolutions (starting with just a comment clarifying what the field actually returns).

@colinhacks
Copy link
Owner

colinhacks commented Feb 4, 2025

ZodError extends Error and the message property is always a string: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/message

The message of a ZodError is a JSON.stringified issues array as has been noted elsewhere. The types are not wrong, and this is an intentional decision to make the message property as informative as possible for logging, etc. You should use .issues to retrieve granular error information rather than JSON.parse(err.message). Everything here is intentional and expected.

Other people on here are describing an unrelated issue: Property error is not defined. This was fixed in #3295 and released in Zod 3.23 last April.

@aaronhipple
Copy link

ZodError extends Error and the message property is always a string: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/message

The message of a ZodError is a JSON.stringified issues array as has been noted elsewhere. The types are not wrong, and this is an intentional decision to make the message property as informative as possible for logging, etc. You should use .issues to retrieve granular error information rather than JSON.parse(err.message). Everything here is intentional and expected.

Makes a lot of sense and is good information -- it'd be extra-useful if it was straightforward to find in documentation or inline in the code (per #3937, which I have updated to include this explanation specifically).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests