Zoom-oauth-sample-app Unexpected token u in JSON at position 0

Description
Sorry for the n00b question.

In trying to follow the zoom-oauth-sample-app instructions, the POST instruction apparently returns an undefined body. Then JSON.parse fails in a way i don’t understand.

Error
Zoom Hello World app listening at PORT: 4000
SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse ()
at Request._callback (/Users/jnw/Zoom/zoom-oauth-sample-app/index.js:33:25)
at self.callback (/Users/jnw/Zoom/zoom-oauth-sample-app/node_modules/request/request.js:185:22)
at Request.emit (events.js:315:20)
at Auth.onRequest (/Users/jnw/Zoom/zoom-oauth-sample-app/node_modules/request/lib/auth.js:132:18)
at Request.auth (/Users/jnw/Zoom/zoom-oauth-sample-app/node_modules/request/request.js:1341:14)
at /Users/jnw/Zoom/zoom-oauth-sample-app/index.js:87:12
at Layer.handle [as handle_request] (/Users/jnw/Zoom/zoom-oauth-sample-app/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/jnw/Zoom/zoom-oauth-sample-app/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/Users/jnw/Zoom/zoom-oauth-sample-app/node_modules/express/lib/router/route.js:112:3)

Which App Type (OAuth / Chatbot / JWT / Webhook)?
OAuth

Which Endpoint/s?
Knowing the API endpoint/s can help us to identify your issue faster. Please link the ones you need help/have a question with.

How To Reproduce (If applicable)
Steps to reproduce the behavior:
Request URL https://zoom.us/oauth/authorize?response_type=code&client_id=gGdMwt7YRuODi12dDLRAQ&redirect_uri=http%3A%2F%2F30f46877.ngrok.io

Screenshots (If applicable)
No fun screenshots. The error message tells it all

Additional context
No add’l context

Hey @jnw,

Can you try logging the req from this line?

Thanks,
Tommy

Thanks! Sure. Here it is (with the code slightly obscured).
I’m about to look at it to see if I find anything odd, but I doubt I’d know.

req is:/ <ref *2> IncomingMessage {
_readableState: ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: ,
flowing: null,
ended: false,
endEmitted: false,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: true,
autoDestroy: false,
destroyed: false,
defaultEncoding: ‘utf8’,
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: true,
decoder: null,
encoding: null,
[Symbol(kPaused)]: null
},
readable: true,
_events: [Object: null prototype] {
end: [Function: resetHeadersTimeoutOnReqEnd]
},
_eventsCount: 1,
_maxListeners: undefined,
socket: <ref *1> Socket {
connecting: false,
_hadError: false,
_parent: null,
_host: null,
_readableState: ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: ,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
destroyed: false,
defaultEncoding: ‘utf8’,
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: false
},
readable: true,
_events: [Object: null prototype] {
end: [Array],
timeout: [Function: socketOnTimeout],
data: [Function: bound socketOnData],
error: [Function: socketOnError],
close: [Array],
drain: [Function: bound socketOnDrain],
resume: [Function: onSocketResume],
pause: [Function: onSocketPause]
},
_eventsCount: 8,
_maxListeners: undefined,
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: ‘utf8’,
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
errored: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object]
},
writable: true,
allowHalfOpen: true,
_sockname: null,
_pendingData: null,
_pendingEncoding: ‘’,
server: Server {
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_connections: 1,
_handle: [TCP],
_usingWorkers: false,
_workers: ,
_unref: false,
allowHalfOpen: true,
pauseOnConnect: false,
httpAllowHalfOpen: false,
timeout: 0,
keepAliveTimeout: 5000,
maxHeadersCount: null,
headersTimeout: 60000,
_connectionKey: ‘6::::4000’,
[Symbol(IncomingMessage)]: [Function: IncomingMessage],
[Symbol(ServerResponse)]: [Function: ServerResponse],
[Symbol(kCapture)]: false,
[Symbol(asyncId)]: 5
},
_server: Server {
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_connections: 1,
_handle: [TCP],
_usingWorkers: false,
_workers: ,
_unref: false,
allowHalfOpen: true,
pauseOnConnect: false,
httpAllowHalfOpen: false,
timeout: 0,
keepAliveTimeout: 5000,
maxHeadersCount: null,
headersTimeout: 60000,
_connectionKey: ‘6::::4000’,
[Symbol(IncomingMessage)]: [Function: IncomingMessage],
[Symbol(ServerResponse)]: [Function: ServerResponse],
[Symbol(kCapture)]: false,
[Symbol(asyncId)]: 5
},
parser: HTTPParser {
‘0’: [Function: parserOnHeaders],
‘1’: [Function: parserOnHeadersComplete],
‘2’: [Function: parserOnBody],
‘3’: [Function: parserOnMessageComplete],
‘4’: [Function: bound onParserExecute],
_headers: ,
_url: ‘’,
socket: [Circular *1],
incoming: [Circular 2],
outgoing: null,
maxHeaderPairs: 2000,
_consumed: true,
onIncoming: [Function: bound parserOnIncoming],
parsingHeadersStart: 0
},
on: [Function: socketListenerWrap],
addListener: [Function: socketListenerWrap],
prependListener: [Function: socketListenerWrap],
_paused: false,
_httpMessage: ServerResponse {
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: true,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: ‘’,
finished: false,
_headerSent: false,
socket: [Circular 1],
_header: null,
_onPendingData: [Function: bound updateOutgoingData],
_sent100: false,
_expect_continue: false,
req: [Circular 2],
locals: [Object: null prototype] {},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
[Symbol(asyncId)]: 9,
[Symbol(kHandle)]: TCP {
reading: true,
onconnection: null,
_consumed: true,
[Symbol(owner)]: [Circular 1]
},
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0
},
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: ‘1.1’,
complete: false,
headers: {
host: ‘30f46877.ngrok.io’,
‘upgrade-insecure-requests’: ‘1’,
‘user-agent’: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36’,
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,
/
;q=0.8,application/signed-exchange;v=b3;q=0.9’,
‘accept-encoding’: ‘gzip, deflate’,
‘accept-language’: ‘en-US,en;q=0.9’,
‘x-forwarded-for’: ‘24.136.51.226’
},
rawHeaders: [
‘Host’,
30f46877.ngrok.io’,
‘Upgrade-Insecure-Requests’,
‘1’,
‘User-Agent’,
‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36’,
‘Accept’,
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,
/
;q=0.8,application/signed-exchange;v=b3;q=0.9’,
‘Accept-Encoding’,
‘gzip, deflate’,
‘Accept-Language’,
‘en-US,en;q=0.9’,
‘X-Forwarded-For’,
‘24.136.51.226’
],
trailers: {},
rawTrailers: ,
aborted: false,
upgrade: false,
url: ‘/?code=HB…SA’, // elided for OpSec
method: ‘GET’,
statusCode: null,
statusMessage: null,
client: <ref *1> Socket {
connecting: false,
_hadError: false,
_parent: null,
_host: null,
_readableState: ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: ,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
destroyed: false,
defaultEncoding: ‘utf8’,
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: false
},
readable: true,
_events: [Object: null prototype] {
end: [Array],
timeout: [Function: socketOnTimeout],
data: [Function: bound socketOnData],
error: [Function: socketOnError],
close: [Array],
drain: [Function: bound socketOnDrain],
resume: [Function: onSocketResume],
pause: [Function: onSocketPause]
},
_eventsCount: 8,
_maxListeners: undefined,
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: ‘utf8’,
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
emitClose: false,
autoDestroy: false,
errored: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object]
},
writable: true,
allowHalfOpen: true,
_sockname: null,
_pendingData: null,
_pendingEncoding: ‘’,
server: Server {
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_connections: 1,
_handle: [TCP],
_usingWorkers: false,
_workers: ,
_unref: false,
allowHalfOpen: true,
pauseOnConnect: false,
httpAllowHalfOpen: false,
timeout: 0,
keepAliveTimeout: 5000,
maxHeadersCount: null,
headersTimeout: 60000,
_connectionKey: ‘6::::4000’,
[Symbol(IncomingMessage)]: [Function: IncomingMessage],
[Symbol(ServerResponse)]: [Function: ServerResponse],
[Symbol(kCapture)]: false,
[Symbol(asyncId)]: 5
},
_server: Server {
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_connections: 1,
_handle: [TCP],
_usingWorkers: false,
_workers: ,
_unref: false,
allowHalfOpen: true,
pauseOnConnect: false,
httpAllowHalfOpen: false,
timeout: 0,
keepAliveTimeout: 5000,
maxHeadersCount: null,
headersTimeout: 60000,
_connectionKey: ‘6::::4000’,
[Symbol(IncomingMessage)]: [Function: IncomingMessage],
[Symbol(ServerResponse)]: [Function: ServerResponse],
[Symbol(kCapture)]: false,
[Symbol(asyncId)]: 5
},
parser: HTTPParser {
‘0’: [Function: parserOnHeaders],
‘1’: [Function: parserOnHeadersComplete],
‘2’: [Function: parserOnBody],
‘3’: [Function: parserOnMessageComplete],
‘4’: [Function: bound onParserExecute],
_headers: ,
_url: ‘’,
socket: [Circular *1],
incoming: [Circular *2],
outgoing: null,
maxHeaderPairs: 2000,
_consumed: true,
onIncoming: [Function: bound parserOnIncoming],
parsingHeadersStart: 0
},
on: [Function: socketListenerWrap],
addListener: [Function: socketListenerWrap],
prependListener: [Function: socketListenerWrap],
_paused: false,
_httpMessage: ServerResponse {
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: undefined,
outputData: ,
outputSize: 0,
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: true,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: ‘’,
finished: false,
_headerSent: false,
socket: [Circular *1],
_header: null,
_onPendingData: [Function: bound updateOutgoingData],
_sent100: false,
_expect_continue: false,
req: [Circular *2],
locals: [Object: null prototype] {},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
[Symbol(asyncId)]: 9,
[Symbol(kHandle)]: TCP {
reading: true,
onconnection: null,
_consumed: true,
[Symbol(owner)]: [Circular *1]
},
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0
},
_consuming: false,
_dumped: false,
next: [Function: next],
baseUrl: ‘’,
originalUrl: ‘/?code=HB…SA’, // elided for OpSec
_parsedUrl: Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: ‘?code=HB…SA’, // elided for OpSec
query: ‘code=HB…SA’, // elided for OpSec
pathname: ‘/’,
path: ‘/?code=HB…SA’, // elided for OpSec
href: ‘/?code=HB…SA’, // elided for OpSec
_raw: ‘/?code=HB…SA’ // elided for OpSec
},
params: {},
query: { code: ‘HB…SA’ }, // elided for OpSec
res: <ref *3> ServerResponse {
_events: [Object: null prototype] { finish: [Function: bound resOnFinish] },
_eventsCount: 1,
_maxListeners: undefined,
outputData: ,
outputSize: 0,
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: true,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: ‘’,
finished: false,
_headerSent: false,
socket: <ref *1> Socket {
connecting: false,
_hadError: false,
_parent: null,
_host: null,
_readableState: [ReadableState],
readable: true,
_events: [Object: null prototype],
_eventsCount: 8,
_maxListeners: undefined,
_writableState: [WritableState],
writable: true,
allowHalfOpen: true,
_sockname: null,
_pendingData: null,
_pendingEncoding: ‘’,
server: [Server],
_server: [Server],
parser: [HTTPParser],
on: [Function: socketListenerWrap],
addListener: [Function: socketListenerWrap],
prependListener: [Function: socketListenerWrap],
_paused: false,
_httpMessage: [Circular *3],
[Symbol(asyncId)]: 9,
[Symbol(kHandle)]: [TCP],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0
},
_header: null,
_onPendingData: [Function: bound updateOutgoingData],
_sent100: false,
_expect_continue: false,
req: [Circular *2],
locals: [Object: null prototype] {},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] { ‘x-powered-by’: [Array] }
},
route: Route { path: ‘/’, stack: [ [Layer] ], methods: { get: true } },
[Symbol(kCapture)]: false
}

BTW, the URL 30f46877.ngrok.io is no longer active.
I’ve shut down that forward.

Found this error was a result of type in .env file.
Thanks.

1 Like

Happy to hear you figured out the issue! :slight_smile:

Thanks,
Tommy

In my case, I didn’t have a typo but I didn’t add the “Redirect URL for OAuth” to the whitelist URL in the App Credentials page

1 Like

@tommy
I tried using my access token in the zoom api test page to change my password (I am a single user account)

However, when I tried to send the PUT message, I got this error:

{
  "code": 1117,
  "message": "Can not update Admin's password"
}

Can you please explain why this happening? How is this API supposed to work if I can’t change my password?

Hey @frakman,

What are you passing in for the {userID} param?

Also, are you using a user or account level OAuth app?

Thanks,
Tommy

Thank you for writing back @tommy.

I am using my email as the {userID}
I am using the account level app.
image

Hey @frakman,

Can you please private message me your email and request body so I can investigate further?

Also due note the enhanced password rules settings:

Thanks,
Tommy

I am getting the same error. There is no typo in my .env file and I have my url redirect in both spots.

SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse ()
at Request._callback (C:\Users\GalloPad\zoom-oauth-sample-app\index.js:29:25)
at self.callback (C:\Users\GalloPad\zoom-oauth-sample-app\node_modules\request\request.js:185:22)
at Request.emit (events.js:210:5)
at Auth.onRequest (C:\Users\GalloPad\zoom-oauth-sample-app\node_modules\request\lib\auth.js:132:18)
at Request.auth (C:\Users\GalloPad\zoom-oauth-sample-app\node_modules\request\request.js:1341:14)
at C:\Users\GalloPad\zoom-oauth-sample-app\index.js:82:12
at Layer.handle [as handle_request] (C:\Users\GalloPad\zoom-oauth-sample-app\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\GalloPad\zoom-oauth-sample-app\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\GalloPad\zoom-oauth-sample-app\node_modules\express\lib\router\route.js:112:3)

Hey @georgiareporting,

Can you console.log the body on this line:

Let me know what is returned so I can help debug.

Thanks,
Tommy

This is my first time doing this. I ‘believe’ I’m doing it correctly. My ngrok forwarding is the same as what’s in my .env file and on redirect.

This error code runs when I console.log body.

{“reason”:“Invalid request : Redirect URI mismatch.”,“error”:“invalid_request”}
access_token: undefined
refresh_token: undefined

1 Like

Now it is working for some reason. It didn’t work the first 50 times and it started to work after I posted the last error. I have no idea. I didn’t change anything.

1 Like

Hey @georgiareporting,

Glad you got it working! The redirect_URI was probably not set in your App Marketplace Settings or in the .env file.

Thanks,
Tommy

Hello @tommy,

I’ve been seeing the same issue.
Tried logging the body as you’d requested in.a response earlier. and this is what I see

console.log(body = {body}, error= {error}, response = ${response});

body = undefined, error=  Error: no auth mechanism defined, response = undefined
SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)
    at Request.request.post [as _callback] (/Users/anagaraju/code/zoom-oauth-app/zoom-oauth-sample-app/index.js:30:25)
    at self.callback (/Users/anagaraju/code/zoom-oauth-app/zoom-oauth-sample-app/node_modules/request/request.js:185:22)
    at Request.emit (events.js:182:13)
    at Auth.onRequest (/Users/anagaraju/code/zoom-oauth-app/zoom-oauth-sample-app/node_modules/request/lib/auth.js:132:18)
    at Request.auth (/Users/anagaraju/code/zoom-oauth-app/zoom-oauth-sample-app/node_modules/request/request.js:1341:14)
    at app.get (/Users/anagaraju/code/zoom-oauth-app/zoom-oauth-sample-app/index.js:83:12)
    at Layer.handle [as handle_request] (/Users/anagaraju/code/zoom-oauth-app/zoom-oauth-sample-app/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/anagaraju/code/zoom-oauth-app/zoom-oauth-sample-app/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/anagaraju/code/zoom-oauth-app/zoom-oauth-sample-app/node_modules/express/lib/router/route.js:112:3)

Repeated retries don’t seem to fix the problem.

Not sure why I see “No auth mechanism defined” as the error, because I choose “OAuth” as the auth mechanism on the first step

Also ensured file is named .env, the way it was suggested here


but to no avail

Thanks

Fixed it. Error on my end. Apologies :slight_smile:

my .env file was in the wrong folder hierarchy.
After moving it to the root directory of the zoom oauth app, I don’t see the error anymore and the response is what was expected

1 Like

Hey @anagaraju,

Happy to hear you got it sorted out! :slight_smile:

Thanks,
Tommy