zod icon indicating copy to clipboard operation
zod copied to clipboard

Cannot get error message from safeParse

Open Creative-Difficulty opened this issue 2 years ago • 11 comments

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 avatar Oct 19 '23 11:10 Creative-Difficulty

@colinhacks pls fix

Creative-Difficulty avatar Oct 19 '23 14:10 Creative-Difficulty

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

amany9000 avatar Oct 22 '23 13:10 amany9000

@amany9000 There's a quite easy workaround

Creative-Difficulty avatar Oct 22 '23 20:10 Creative-Difficulty

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?

blackram avatar Dec 04 '23 10:12 blackram

No it isn't

Creative-Difficulty avatar Dec 04 '23 11:12 Creative-Difficulty

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)

cloudbring avatar Dec 21 '23 01:12 cloudbring

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

jeremydaly avatar Feb 04 '24 15:02 jeremydaly

This has nothing to do with strict mode.

Creative-Difficulty avatar Feb 04 '24 17:02 Creative-Difficulty

I have same problem, image image

impuLssse avatar Feb 08 '24 16:02 impuLssse

This is still an issue

Creative-Difficulty avatar Feb 08 '24 18:02 Creative-Difficulty

Same here. image

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

nbolton avatar Feb 15 '24 14:02 nbolton

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

GrahamS-Quartech avatar Mar 20 '24 16:03 GrahamS-Quartech

Same, currenty facing this issue

Eiley2 avatar Mar 24 '24 07:03 Eiley2

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

Shisuki avatar Mar 28 '24 15:03 Shisuki

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

sir-captainmorgan21 avatar Mar 30 '24 20:03 sir-captainmorgan21

Thanks for the solution my friend

vjlkof avatar Apr 20 '24 22:04 vjlkof

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.

colinhacks avatar Apr 21 '24 22:04 colinhacks

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 avatar May 03 '24 02:05 Pinky030

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
    } 

Pinky030 avatar May 03 '24 02:05 Pinky030

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 😄

Downster avatar May 20 '24 16:05 Downster