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

Next.js Build Fails with 400 Bad Request After 202 Pages When Using ky, Works with fetch #646

Open
MhL5 opened this issue Oct 24, 2024 · 4 comments

Comments

@MhL5
Copy link

MhL5 commented Oct 24, 2024

I'm encountering an issue during the build process of my Next.js app. Everything works perfectly in development mode (next dev), but when I try to build the application (next build), I consistently get an error after successfully generating around 202 static pages.

The error occurs when using ky to fetch markdown files for blog posts. The first page that typically fails is page 202, with the error message showing a 400 Bad Request. However, when I switch to fetch for the same API call, the build completes successfully without any issues.

Error Log

HTTPError: Request failed with status code 400 Bad Request: GET http://blog.vsim.space/posts/markdown/2.md
    at o (D:\-code\work\vsim\.next\server\chunks\2576.js:1:82169)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async T._retry (D:\-code\work\vsim\.next\server\chunks\2576.js:1:85858)
    at async i.<computed> [as text] (D:\-code\work\vsim\.next\server\chunks\2576.js:1:82789)
    at async l (D:\-code\work\vsim\.next\server\app\[lang]\(with-navigation)\blog\page.js:1:17639)
    at async u (D:\-code\work\vsim\.next\server\app\[lang]\(with-navigation)\tips\[tipSlug]\page.js:1:6941)
Generating static pages (208/228)  [    ]
Error occurred prerendering page "/tr/tips/vsim-tip-code-delivery". Read more: https://nextjs.org/docs/messages/prerender-error

The issue arises when using ky:

const md = await ky
    .get(data.markdown_path, { cache: "no-store", timeout: 5 * 60 * 1000 })
    .text();

When I switch to fetch, the build succeeds without any issues:

const resMd = await fetch(data.markdown_path, { cache: "no-store" });
const md = await resMd.text();
@sholladay
Copy link
Collaborator

sholladay commented Oct 25, 2024

Can you try to log the error's response body?

I am hoping the server's response will indicate what part of the request is bad.

@MhL5
Copy link
Author

MhL5 commented Oct 25, 2024

r [HTTPError]: Request failed with status code 400 Bad Request: GET http://blog.space/posts/markdown/2.md
    at o (D:\-code\work\vsim\.next\server\chunks\2576.js:1:82169)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async T._retry (D:\-code\work\vsim\.next\server\chunks\2576.js:1:85858)
    at async i.<computed> [as text] (D:\-code\work\vsim\.next\server\chunks\2576.js:1:82789)
    at async l (D:\-code\work\vsim\.next\server\app\[lang]\(with-navigation)\blog\[blogSlug]\page.js:1:11558)
    at async u (D:\-code\work\vsim\.next\server\app\[lang]\(with-navigation)\tips\[tipSlug]\page.js:1:6941) {
  response: Response {
    status: 400,
    statusText: 'Bad Request',
    headers: Headers {
      server: 'cloudflare',
      date: 'Fri, 25 Oct 2024 13:51:53 GMT',
      'content-type': 'text/html',
      'content-length': '253',
      connection: 'close',
      'cf-ray': '-'
    },
    body: ReadableStream { locked: false, state: 'readable', supportsBYOB: true },
    bodyUsed: false,
    ok: false,
    redirected: false,
    type: 'basic',
    url: 'http://blog.space/posts/markdown/2.md'
  },
  request: Request {
    method: 'GET',
    url: 'http://blog.space/posts/markdown/2.md',
    headers: Headers { accept: 'text/*' },
    destination: '',
    referrer: 'about:client',
    referrerPolicy: '',
    mode: 'cors',
    credentials: 'same-origin',
    cache: 'default',
    redirect: 'follow',
    integrity: '',
    keepalive: false,
    isReloadNavigation: false,
    isHistoryNavigation: false,
    signal: AbortSignal { aborted: false }
  },
  options: {
    method: 'GET',
    headers: Headers {},
    hooks: {
      beforeRequest: [],
      beforeRetry: [],
      afterResponse: [],
      beforeError: []
    },
    prefixUrl: '',
    retry: {
      limit: 2,
      methods: [Array],
      statusCodes: [Array],
      afterStatusCodes: [Array],
      maxRetryAfter: Infinity,
      backoffLimit: Infinity,
      delay: [Function: delay]
    },
    throwHttpErrors: true,
    timeout: 10000,
    fetch: [Function: bound c] AsyncFunction,
    signal: AbortSignal { aborted: false },
    duplex: 'half'
  }
}

this is the error
i tried increasing the timeout to 5 minutes it didnt help

i have tried to read the response body using await error.response.json() but its not json its html

SyntaxError: Unexpected token '<', "<html>
<h"... is not valid JSON
    at JSON.parse (<anonymous>)
    at parseJSONFromBytes (node:internal/deps/undici/undici:5472:19)
    at successSteps (node:internal/deps/undici/undici:5454:27)
    at fullyReadBody (node:internal/deps/undici/undici:4381:9)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async consumeBody (node:internal/deps/undici/undici:5463:7)
    at async l (D:\-code\work\vsim\.next\server\app\[lang]\(with-navigation)\blog\[blogSlug]\page.js:1:11742)
    at async p (D:\-code\work\vsim\.next\server\app\[lang]\(with-navigation)\blog\[blogSlug]\page.js:1:6954) {
  digest: '408536040'
}

this is response body: await err.response.text()
I don’t understand why this issue only occurs with ky for certain pages, consistently starting at page 202, while it doesn’t happen with fetch.

    '<html>\r\n' +
    '<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>\r\n' +
    '<body>\r\n' +
    '<center><h1>400 Bad Request</h1></center>\r\n' +
    '<center>The plain HTTP request was sent to HTTPS port</center>\r\n' +
    '<hr><center>cloudflare</center>\r\n' +
    '</body>\r\n' +
    '</html>\r\n'

@Antoine-Regembal
Copy link

Antoine-Regembal commented Nov 20, 2024

Hi,

I'm facing the same issue of a request working fine with fetch but failing with Ky IF I extend ky and use things like "prefixUrl" or "beforeRequest" hook (it still works fine for me if I directly use the base Ky instance without extending it)

So I'm not sure what makes the error happen but there is a strange behavior here

The server responding with the 400 bad request is also behind Cloudflare, there might be something to do with it

Edit:

I logged the response error and it says the format of one of my body value if invalid (id in my case)
I checked the request and it looks good

The request below doesn't work:

const api = ky.extend({
  prefixUrl: process.env.API_URL,
  hooks: {
    beforeRequest: [
      (request) => {
        request.headers.set('Content-Type', 'application/json');
        request.headers.set('Authorization', `Basic ${base64EncodedBasic}`);
      },
    ],
  },
});

const body = {
      id: "fooBar",
};

await this.api
      .post('my-api-endpoint', {
        body: JSON.stringify(body)
      })
      .json();


// RESPONSE 400 BAD REQUEST
/* {
  resultId: 'validation_error',
  message: 'Validation error(s) occurred. Please review the error(s) and address accordingly.',
  validationErrors: [
    {
      message: 'The format of the xxxx is invalid.',
      fieldPath: 'id',
      errorId: 'xxxxxx'
    }
  ]
} */

while this one works well:

const body = {
      id: "fooBar",
};

await ky.post(`${process.env.API_URL}/my-api-endpoint`, {
      body: JSON.stringify(body),
      headers: {
        Authorization: `Basic ${base64EncodedBasic}`,
        'Content-Type': 'application/json',
      },
    }).json();

@sholladay would you have any idea why ?

@sholladay
Copy link
Collaborator

I would suggest checking to see if one of the requests is repeated. That might explain why the server complains about the id even if it looks good.

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

3 participants