oak: Getting "The response is not writable." error

This is my first time using Oak, and I’m running into an error that is making me scratch my head quite a bit. I can provide more code if need but it seems isolated to this chunk. I’m getting this error:

error: Uncaught Error: The response is not writable.
      throw new Error("The response is not writable.");
            ^
    at Response.set body (https://deno.land/x/oak/response.ts:120:13)
    at file:///C:/Users/TARS/projects/deno-elixir/src/app.ts:31:24

but I don’t even have to adjust my response to get it to go away. I can just comment out the line above setting the response and it works. Returns “random string” in the body like expected.:

.get('/games', async (context) => {
		// const gamesResponse = await API.get("/games");
		context.response.body = "random string";
	})

But if I uncomment that line back into the code, don’t change the response body and keep it as that random string, it crashes with that error. This errors out:

.get('/games', async (context) => {
		const gamesResponse = await API.get("/games");
		context.response.body = "random string";
	})

I have no idea what could be causing that line to be affecting the next line, but the API.get request is fulfilled, I get a 200 and the data I’m expecting to store in the variable gamesResponse, but something about context.response.body doesn’t like that line.

Apologies if the problem is obvious, I’m still a junior dev and this is my first dive into Deno and using this package.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 12
  • Comments: 22 (5 by maintainers)

Commits related to this issue

Most upvoted comments

I had the same problem on routes that used a JWT auth middleware, my solution was to append await before my next() call, so instead of having:

if(token && csrfHeader) {
    if((await validateJwt(token, key)).isValid && validateCSRF(csrfCookie, csrfHeader)) {
       next()
    }

...

}

I changed it to:

if(token && csrfHeader) {
    if((await validateJwt(token, key)).isValid && validateCSRF(csrfCookie, csrfHeader)) {
       await next()
    }

...

}

It works fine, and no errors 😉

Apparently, for me the problem is that I didn’t return a Promise in the middleware, my code was something like this:

app.use((ctx, next) => {
  doSomething((result) => {
    ctx.response.body.result
    next()
  })
})

However, since I’m not return a promise, this line was immediately invoked even before doSomething finished, which will in turn turn the response unwritable.

So, by returning a promise as follows, I don’t face this problem anymore.

app.use((ctx, next) => {
  return new Promise(resolve => {
    doSomething((result) => {
      ctx.response.body.result
      resolve()
    })
  })
  .then(next)
})

Dear All,

I have the similar problem when using some middleware. The problem exist inside async await function, where if await is missed before next(). Please don’t forget to use await before next() or other method inside asycn function.

Regards

I also replaced next()

by await next()

–> this works fine in my case.

after this the controller content can be something like:

    getChatResponse: async ({ request, response }: { request: any; response: any }) => {
        const apiResult:any = await ResponseProvider.getResponse()
        response.body = apiResult
    }

it seems that the problem occurs because the function returns before the body is written, what I’m really confused by is that when using promises, oak awaits the promise and then disables writing but when using async/await, even though the function still returns a Promise<void>, it is not awaited

this error also occurs when I call: await Deno.readFile …

I have create a repo with a small example of where I have been hitting this issue.

https://github.com/LukeShay/oak-response-not-writable

@kitsonk I think it might be worthwhile to re-evaluate #156, considering that most of the users that face this error is due to human error rather than library bug, which can be avoided with the stricter middleware types.

Same error here.

When I try to fetch asynchronously some data from my DB with mongo@v0.7.0, I get The response is not writable error.

.post('/uploadFile/:projectId', upload('uploads'), async(context: any)=>{
  // Do stuff
  const project: Project | undefined = await projects.findOne({
    _id: { "$oid": context.params.projectId}
  })
  // Do stuff
  context.response.body = 'Any response'
})

If I remove this DB request, everything works fine, but this await seems to cause the problem. Could be upload middleware doing somthing here?

BTW, I found a way to make it work, moving this request to a middleware and passing the information I need through the context.

const checkProject = async(context: any, next: any) => {
  const project = await projects.findOne({_id: { $oid: context.params.projectId}})
  if(project){
    context.project = project
    await next()
  }
}

 // ...
router
  .post('/uploadFile/:projectId', checkProject, upload('uploads'), async(context: any)=>{
  // Do stuff
  const project: Project | undefined = context.project
  // Do stuff
  context.response.body = 'Any response'
}))

}