S3 Upload Failing Silently in Production

I’m struggling to debug a NextJS API that is working in development (via localhost) but is silently failing in production.

Below, the two console.log statements are not returning, so I suspect that the textToSpeech call is not executing correctly, potentially in time?

I’m not sure how to rectify, happy to debug as directed to resolve this!

const faunadb = require('faunadb')
const secret = process.env.FAUNADB_SECRET_KEY
const q = faunadb.query
const client = new faunadb.Client({ secret })
const TextToSpeechV1 = require('ibm-watson/text-to-speech/v1')
const { IamAuthenticator } = require('ibm-watson/auth')
const AWS = require('aws-sdk')
const { randomUUID } = require('crypto')
import { requireAuth } from '@clerk/nextjs/api'

module.exports = requireAuth(async (req, res) => {
  try {
    const s3 = new AWS.S3({
      accessKeyId: process.env.AWS_ACCESS_KEY,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY

    const textToSpeech = new TextToSpeechV1({
      authenticator: new IamAuthenticator({
        apikey: process.env.IBM_API_KEY
      serviceUrl: process.env.IBM_SERVICE_URL

    const uuid = randomUUID()

    const { echoTitle, chapterTitle, chapterText } = req.body

    const synthesizeParams = {
      text: chapterText,
      accept: 'audio/mp3',
      voice: 'en-US_KevinV3Voice'

      .then(buffer => {
        const s3Params = {
          Bucket: 'waveforms/audioform',
          Key: `${uuid}.mp3`,
          Body: buffer.result,
          ContentType: 'audio/mp3',
          ACL: 'public-read'


        s3.upload(s3Params, function (s3Err, data) {
          if (s3Err) throw s3Err
          console.log(`File uploaded successfully at ${data.Location}`)
      .catch(err => {
        console.log('error:', err)

    const dbs = await client.query(
      q.Create(q.Collection('audioform'), {
        data: {
          title: echoTitle,
          published: 2022,
          leadAuthor: 'winter',
          user: req.session.userId,
          authors: 1,
          playTime: 83,
          chapters: 1,
          gpt3Description: '',
          likes: 20,
          trackURL: `https://waveforms.s3.us-east-2.amazonaws.com/audioform/${uuid}.mp3`,
          albumTracks: [
              title: chapterTitle,
              text: chapterText,
              trackURL: `https://waveforms.s3.us-east-2.amazonaws.com/audioform/${uuid}.mp3`
  } catch (e) {
    res.status(500).json({ error: e.message })


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Replace the async fragments something like this, assuming they are meant to be executed sequentially.

try {
  // code removed here for clarity
  const buffer = await textToSpeech.synthesize(synthesizeParams);

  const s3Params = {
    Bucket: 'waveforms/audioform',
    Key: `${uuid}.mp3`,
    Body: buffer.result,
    ContentType: 'audio/mp3',
    ACL: 'public-read'

  await s3.upload(s3Params).promise();

  const dbs = await client.query(...);

} catch (e) {
  res.status(500).json({ error: e.message });

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x