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

ImageResponse type error on route after updating to 13.5.1 #55604

Closed
1 task done
Dannymx opened this issue Sep 19, 2023 · 25 comments · Fixed by #55654
Closed
1 task done

ImageResponse type error on route after updating to 13.5.1 #55604

Dannymx opened this issue Sep 19, 2023 · 25 comments · Fixed by #55654
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. locked TypeScript Related to types with Next.js.

Comments

@Dannymx
Copy link
Contributor

Dannymx commented Sep 19, 2023

Link to the code that reproduces this issue

https://github.com/Dannymx/shockinglemon.com/tree/develop

To Reproduce

  1. Clone repo
  2. next build
  3. See type error on GET route handler

Current vs. Expected behavior

Current:

app/api/og/route.tsx
Type error: Route "app/api/og/route.tsx" has an invalid export:
  "Promise<NextResponse<unknown> | ImageResponse>" is not a valid GET return type:
    Expected "Response | Promise<Response>", got "Promise<NextResponse<unknown> | ImageResponse>".
      Expected "Promise<Response>", got "Promise<NextResponse<unknown> | ImageResponse>".
        Expected "Response", got "NextResponse<unknown> | ImageResponse".

 ELIFECYCLE  Command failed with exit code 1.

Expected: no type errors

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

next info    

    Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.6.0: Wed Jul  5 22:21:53 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T6020
    Binaries:
      Node: 18.17.1
      npm: 9.6.7
      Yarn: N/A
      pnpm: 8.7.5
    Relevant Packages:
      next: 13.5.1
      eslint-config-next: 13.5.1
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.2.2
    Next.js Config:
      output: N/A

Which area(s) are affected? (Select all that apply)

App Router, TypeScript (plugin, built-in types)

Additional context

This started happening after updating to 13.5.1

NEXT-1639

@Dannymx Dannymx added the bug Issue was opened via the bug report template. label Sep 19, 2023
@github-actions github-actions bot added the TypeScript Related to types with Next.js. label Sep 19, 2023
@Dannymx Dannymx changed the title Type error on route after updating to 13.5.1 ImageResponse type error on route after updating to 13.5.1 Sep 19, 2023
@jackypan1989
Copy link

Me too.

 "Promise<NextResponse<{ url: string | null; }> | NextResponse<{ message: any; }> | undefined>" is not a valid GET return type:
[next]     Expected "Response | Promise<Response>", got "Promise<NextResponse<{ url: string | null; }> | NextResponse<{ message: any; }> | undefined>".
[next]       Expected "Promise<Response>", got "Promise<NextResponse<{ url: string | null; }> | NextResponse<{ message: any; }> | undefined>".
[next]         Expected "Response", got "NextResponse<{ url: string | null; }> | NextResponse<{ message: any; }> | undefined".
[next]           Expected "Response", got "undefined".

@smorimoto
Copy link
Contributor

smorimoto commented Sep 19, 2023

You should be able to fix that by replacing it with the newly introduced file opengraph-image.tsx.

app/api/og/route.tsx -> app/opengraph-image.tsx

You may need to add some segment config at the same time.

+ export const alt = "Open Graph";
+ export const contentType = "image/png";

@smorimoto
Copy link
Contributor

If you want to use both opengraph-image.tsx and twitter-image.tsx, you may want to export a fantastic image component from og.tsx and make it shared for those 2 files 🙂

@hipdev
Copy link

hipdev commented Sep 19, 2023

Just in case, replace your Request type with NextRequest like:

import type { NextRequest } from 'next/server'

...
export async function GET(request: NextRequest) {
...
}

I had the same TS error after updating to 13.5.1 but this fix it.

@icyJoseph
Copy link
Contributor

You should be able to fix that by replacing it with the newly introduced file opengraph-image.tsx.

app/api/og/route.tsx -> app/opengraph-image.tsx

You may need to add some segment config at the same time.

+ export const alt = "Open Graph";
+ export const contentType = "image/png";

What if alt depends on a dynamic parameter?

@smorimoto
Copy link
Contributor

What if alt depends on a dynamic parameter?

@icyJoseph Isn't this line of documentation the answer for you?

By default, generated images are statically optimized (generated at build time and cached) unless they use dynamic functions or uncached data.

@icyJoseph
Copy link
Contributor

icyJoseph commented Sep 19, 2023

@smorimoto nope, because I am generating metadata, where I calculate a special alt tag based of the route.

The ImageResponse doesn't accept alt. So I'd have to use the same static alt text. Unless there's a way to export alt as a function that receives the slug, or if I could pass it to the ImageResponse.

Even if it's generated on demand, how do we use dynamic parameters from the route when calculating the alt text, that's the question.

I'm also still investigating :)

@smorimoto
Copy link
Contributor

@icyJoseph Oh, I get it. Try this: generateImageMetadata

@alex289
Copy link

alex289 commented Sep 19, 2023

I got it to work just by replacing the import of the ImageResponse from @vercel/og to next/server

@rodolphoasb
Copy link

Hey, I don't think this is just related to og images. I'm also seeing this error on a completely different route (and this is only happening after migrating to v 13.5.1).

Here's the error on vercel when I'm trying to deploy:

Type error: Route "src/app/api/v1/product/createForOtherUser/route.ts" has an invalid export:
--
16:24:57.436 | "Promise<Response \| undefined>" is not a valid POST return type:
16:24:57.436 | Expected "Response \| Promise<Response>", got "Promise<Response \| undefined>".
16:24:57.436 | Expected "Promise<Response>", got "Promise<Response \| undefined>".
16:24:57.436 | Expected "Response", got "Response \| undefined".
16:24:57.436 | Expected "Response", got "undefined".
16:24:57.436 |  
16:24:57.556 | Error: Command "npm run build" exited with 1

And here's my code:

import { prisma } from "@/lib/prisma";
import { auth } from "@clerk/nextjs";
import { z } from "zod";

const apiRequestValidator = z.object({
  productName: z.string().min(3).max(255),
  productCategory: z.string(),
  productDescription: z.string().min(2).max(1000),
  productPrice: z.number().min(0),
  creatingAsAdmin: z.boolean(),
  userPhone: z.string(),
  userName: z.string(),
});

export type ApiRequest = z.infer<typeof apiRequestValidator>;

export async function POST(req: Request) {
  const body = await req.json();
  const { userId } = auth();

  if (!userId) {
    return new Response("Unauthorized", { status: 401 });
  }

  const {
    productName,
    productCategory,
    productDescription,
    productPrice,
    creatingAsAdmin,
    userName,
    userPhone,
  } = apiRequestValidator.parse(body);

  // Check if user is admin
  const user = await prisma.user.findUnique({
    where: {
      id: userId,
    },
  });

  if (user?.userRole !== "ADMIN") {
    return new Response("Unauthorized", { status: 401 });
  }

  if (creatingAsAdmin) {
    try {
      const result = await prisma.product.create({
       ...
    })

      return new Response(
        JSON.stringify({
          productId: result.id,
        }),
        { status: 200 }
      );
    } catch (error) {
      return new Response("Invalid request", { status: 400 });
    }
  }
}

@Dannymx
Copy link
Contributor Author

Dannymx commented Sep 19, 2023

I got it to work just by replacing the import of the ImageResponse from @vercel/og to next/server

This fixes it, thanks. I just noticed the docs were updated too.

@balazsorban44 balazsorban44 added the linear: next Confirmed issue that is tracked by the Next.js team. label Sep 20, 2023
@huozhi
Copy link
Member

huozhi commented Sep 20, 2023

Hi, can you try to use import { ImageResponse } from 'next/server'? We're working on the fix about the type checking now

@kodiakhq kodiakhq bot closed this as completed in #55654 Sep 20, 2023
kodiakhq bot pushed a commit that referenced this issue Sep 20, 2023
### What?

Bump these packages to their latest. (Bumped `satori` too to avoid multiple versions in the repo)

### Why?

Follow-up of #55187

### How?

Updated the original package applying the changes from #55187

Closes NEXT-1639
Fixes #55604

[Slack thread](https://vercel.slack.com/archives/C03S8ED1DKM/p1695169119558899)
@huozhi
Copy link
Member

huozhi commented Sep 20, 2023

Upgrading @vercel/og to 0.5.15 will work, it was failed due to the type mismatching since we introduced a more strict type checking that app routes should return Response | Promise<Response>.

We're also aliasing @vercel/og to the built-in ImageResponse where is from "next/server" to avoid duplicated bundling that might blow up your route bundle size. So you don't need to install any @vercel/og package and you can just import it from next/server.

@mocca-dev
Copy link

mocca-dev commented Sep 21, 2023

Just in case, replace your Request type with NextRequest like:

import type { NextRequest } from 'next/server'

...
export async function GET(request: NextRequest) {
...
}

I had the same TS error after updating to 13.5.1 but this fix it.

Hi, I'm having the same problem but with the NextResponse...here are a capture of the error message when I run the build command.

`⚠ Compiled with warnings

./node_modules/@whatwg-node/fetch/dist/node-ponyfill.js
Critical dependency: the request of a dependency is an expression

Import trace for requested module:
./node_modules/@whatwg-node/fetch/dist/node-ponyfill.js
./node_modules/graphql-yoga/esm/server.js
./node_modules/graphql-yoga/esm/index.js
./app/api/graphql/route.ts

Linting and checking validity of types .Failed to compile.

app/api/auth/signup/route.ts
Type error: Route "app/api/auth/signup/route.ts" has an invalid export:
"Promise<NextResponse | undefined>" is not a valid GET return type:
Expected "Response | Promise", got "Promise<NextResponse | undefined>".
Expected "Promise", got "Promise<NextResponse | undefined>".
Expected "Response", got "NextResponse | undefined".
Expected "Response", got "undefined".`

Could you help me with this? thanks

@anthonyverducci
Copy link

I don't think this is just related to images, either. My API routes were working just fine until I upgraded to 13.5.2 this morning. I'm getting the following error when I deploy to Vercel:

Type error: Route "src/app/api/providers/create-provider-bios/route.ts" has an invalid export:
--
09:01:44.392 | "Promise<NextResponse<string> \| undefined>" is not a valid PUT return type:
09:01:44.392 | Expected "Response \| Promise<Response>", got "Promise<NextResponse<string> \| undefined>".
09:01:44.392 | Expected "Promise<Response>", got "Promise<NextResponse<string> \| undefined>".
09:01:44.393 | Expected "Response", got "NextResponse<string> \| undefined".
09:01:44.393 | Expected "Response", got "undefined".

In my route, I'm using both NextRequest and NextResponse imports from next/server.

@balazsorban44
Copy link
Member

Let's open a new issue for these! ImageResponse should be correct now

@rodolphoasb
Copy link

Hey, @balazsorban44, I think there's an open issue for this on #55623

@balazsorban44
Copy link
Member

That looks slightly different, specifically for redirect().

@Revaycolizer
Copy link

Revaycolizer commented Sep 21, 2023

nexterror

I don't think this is just related to images, either. My API routes were working just fine until I upgraded to 13.5.2 this morning. I'm getting the following error when I deploy to Vercel:

Type error: Route "src/app/api/search/route.ts" has an invalid export:
--
09:01:44.392 | "Promise<NextResponse<string> \| undefined>" is not a valid GET return type:
09:01:44.392 | Expected "Response \| Promise<Response>", got "Promise<NextResponse<string> \| undefined>".
09:01:44.392 | Expected "Promise<Response>", got "Promise<NextResponse<string> \| undefined>".
09:01:44.393 | Expected "Response", got "NextResponse<string> \| undefined".
09:01:44.393 | Expected "Response", got "undefined".

In my route, I'm using both NextRequest and NextResponse imports from next/server.

@tjhorwood
Copy link

tjhorwood commented Sep 22, 2023

@Revaycolizer @anthonyverducci Not sure if this will help, I was getting the same exact issue on some of my api routes. It came down to the more nested if/then statements in the try/catch. Reducing the number of conditions in the catch seemed to resolve the problem for me.

For instance changing:

} catch (error) {
    const errorMessage = 'An error occured!';
    if (error instanceof Error) {
      const isDuplicate = error.message.includes(
        'Unique constraint failed on the fields: (`username`)',
      );
      if (isDuplicate) {
        return NextResponse.json(
          { message: 'Username is already taken, please try another one' },
          { status: 501 },
        );
      } else {
        return NextResponse.json({ message: errorMessage }, { status: 503 });
      }
    }
  }

to this:

catch (error) {
    const errorMessage =
      error instanceof Error
        ? error.message
        : 'An error occured. Please check username and password.';
    return NextResponse.json(
      { message: errorMessage, ok: false },
      { status: 503 },
    );
  }

@Revaycolizer
Copy link

But I'm not having any if conditions

timneutkens pushed a commit that referenced this issue Sep 25, 2023
### What

#51394 introduced a pretty strict type of return value of route type
that causing failure with `next build`.
There're few ways of writing a app route, it could contain few return
values based on the usage:

* return a `Response` or promise of it
* return `NextResponse` of promise of it, since it's extended from
`Response`, same type
* use `redirect()` or `notFound(), since it returns `never`, and the
below code is not reached, the handler itself could still return void.
e.g. using `redirect` in a `GET` route

We loosed the type so `redirect()` can be still allowed without
specifying the return value there.
Related typescript issue:
microsoft/TypeScript#16608 (comment)

### How
* Re-enable the bail on types / build error in the app-routes tests
* Separate the tests, move runtime erroring ones to
`test/e2e/app-dir/app-routes-errors`
* Add new case to app-routes tests of mixed return value

Closes #55623 
Related #55604
@huozhi
Copy link
Member

huozhi commented Sep 25, 2023

We had a fix in 13.5.3, can you try to upgrade to the latest version? Thanks!

@cvogl
Copy link

cvogl commented Sep 26, 2023

Unfortunately the patch was not a fix, at least not here.
tl;dr Code unchanged since July, breaking of build persists with Next 13.5.3 (but works with 13.4.19)

I have just upgraded to Next 13.5.3 and linter breaks build with the same error message as with 13.5.1:

Type error: Route "src/app/api/frontend/checksession/route.ts" has an invalid export:
"Promise<false | NextResponse<{ status: string; }>>" is not a valid GET return type:
Expected "void | Response | Promise<void | Response>", got "Promise<false | NextResponse<{ status: string; }>>".
Expected "Promise<void | Response>", got "Promise<false | NextResponse<{ status: string; }>>".
Expected "void | Response", got "false | NextResponse<{ status: string; }>".
Expected "void | Response", got "boolean".

Double-checked the build after downgrade to 13.4.19: still finishing successfully.
(Which is no surprise: the code in that module was not touched after August 2.)

For us, it's also unrelated to images.

Thank you for investigating!

@huozhi
Copy link
Member

huozhi commented Sep 26, 2023

@cvogl please check the response here

@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. locked TypeScript Related to types with Next.js.
Projects
None yet
Development

Successfully merging a pull request may close this issue.