Status 415 "Unsupported Media Type" errors on simple Storefront API GraphQL queries

Solved
blimpmason
Tourist
4 1 1

I'm getting Status 415 "Unsupported Media Type" errors on every storefront API GraphQL request I make. The Storefront API is enabled and I've double checked permissions and the storefront access token. Here are my request details:

Url: 
'https://erica-weiner.myshopify.com/api/2020-10/graphql'

Headers:
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': '155fd2311f650f31692e97758ad40ddc'

Query:
query Collection($handle:String!) {
  {
    collectionByHandle(handle: $handle){
      id
      title
      handle
    }
  }
}

Full error log:

 

Error: Request failed with status code 415
at e.exports (/Users/davidgross/Sites/erica-weiner/web/functions/shopify-collection-sync.js:6:1780)
at e.exports (/Users/davidgross/Sites/erica-weiner/web/functions/shopify-collection-sync.js:6:10819)
at IncomingMessage.<anonymous> (/Users/davidgross/Sites/erica-weiner/web/functions/shopify-collection-sync.js:6:27872)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (_stream_readable.js:1224:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
config: {
url: 'https://erica-weiner.myshopify.com/api/2020-10/graphql',
method: 'post',
data: '{"query":"query Collection($handle:String!) { \\n {\\n collectionByHandle(handle: $handle){\\n id\\n title\\n handle\\n }\\n }\\n}","variables":{"handle":"for-mom"}}',
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': '155fd2311f650f31692e97758ad40ddc',
'User-Agent': 'axios/0.20.0',
'Content-Length': 180
},
transformRequest: [ [Function (anonymous)] ],
transformResponse: [ [Function (anonymous)] ],
timeout: 0,
adapter: [Function (anonymous)],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus]
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
socket: [Function (anonymous)],
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
timeout: [Function (anonymous)],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: 'erica-weiner.myshopify.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 10,
connecting: false,
_hadError: false,
_parent: null,
_host: 'erica-weiner.myshopify.com',
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular *1],
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: 1239,
[Symbol(kHandle)]: [TLSWrap],
[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,
[Symbol(connect-options)]: [Object]
},
_header: 'POST /api/2020-10/graphql HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/json\r\n' +
'X-Shopify-Storefront-Access-Token: 155fd2311f650f31692e97758ad40ddc\r\n' +
'User-Agent: axios/0.20.0\r\n' +
'Content-Length: 180\r\n' +
'Host: erica-weiner.myshopify.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/api/2020-10/graphql',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
socket: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 415,
statusMessage: 'Unsupported Media Type',
client: [TLSSocket],
_consuming: false,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://erica-weiner.myshopify.com/api/2020-10/graphql',
redirects: [],
[Symbol(kCapture)]: false
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 180,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://erica-weiner.myshopify.com/api/2020-10/graphql',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'content-type': [Array],
'x-shopify-storefront-access-token': [Array],
'user-agent': [Array],
'content-length': [Array],
host: [Array]
}
},
response: {
status: 415,
statusText: 'Unsupported Media Type',
headers: {
date: 'Fri, 18 Dec 2020 20:32:32 GMT',
'transfer-encoding': 'chunked',
connection: 'close',
'x-sorting-hat-podid': '83',
'x-sorting-hat-shopid': '1565502',
'x-request-id': '27a9e392-134f-4410-b128-f41458f21911',
'x-shopify-stage': 'production',
'x-content-type-options': 'nosniff',
'x-download-options': 'noopen',
'x-permitted-cross-domain-policies': 'none',
'x-xss-protection': '1; mode=block',
'x-dc': 'gcp-us-central1,gcp-us-central1',
'cf-cache-status': 'DYNAMIC',
'cf-request-id': '071926ed180000e50632ad2000000001',
'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
server: 'cloudflare',
'cf-ray': '603ba75b5c11e506-LAX',
'alt-svc': 'h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400'
},
config: {
url: 'https://erica-weiner.myshopify.com/api/2020-10/graphql',
method: 'post',
data: '{"query":"query Collection($handle:String!) { \\n {\\n collectionByHandle(handle: $handle){\\n id\\n title\\n handle\\n }\\n }\\n}","variables":{"handle":"for-mom"}}',
headers: [Object],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
adapter: [Function (anonymous)],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus]
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [TLSSocket],
_header: 'POST /api/2020-10/graphql HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'Content-Type: application/json\r\n' +
'X-Shopify-Storefront-Access-Token: 155fd2311f650f31692e97758ad40ddc\r\n' +
'User-Agent: axios/0.20.0\r\n' +
'Content-Length: 180\r\n' +
'Host: erica-weiner.myshopify.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/api/2020-10/graphql',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: ''
},
isAxiosError: true,
toJSON: [Function (anonymous)]
}
Response with status 500 in 187 ms.
◈ Error during invocation: TypeError: Cannot read property 'message' of undefined
at Object.m [as handler] (/Users/davidgross/Sites/erica-weiner/web/functions/shopify-collection-sync.js:20:14280)
at processTicksAndRejections (internal/process/task_queues.js:97:5)

 

Accepted Solution (1)
blimpmason
Tourist
4 1 1

This is an accepted solution.

After more troubleshooting I figured out the reason for my 415 errors and managed to get the requests working:

1. The axios request headers did not include Accept: "application/json",

 

Accept: "application/json"

 

2. I had an extra set of brackets in my graphql query. Here's the corrected query:

 

query Collection($handle:String!) { 
  collectionByHandle(handle: $handle){
    id
    title
    handle
    products(first:10) {
      edges {
        node {
          id
        }
      }
    }
  }
}

 

and 3. I was JSON.stringify-ing the axios data payload unnecessarily. Passing the data payload object directly without stringifying works.

View solution in original post

Reply 1 (1)
blimpmason
Tourist
4 1 1

This is an accepted solution.

After more troubleshooting I figured out the reason for my 415 errors and managed to get the requests working:

1. The axios request headers did not include Accept: "application/json",

 

Accept: "application/json"

 

2. I had an extra set of brackets in my graphql query. Here's the corrected query:

 

query Collection($handle:String!) { 
  collectionByHandle(handle: $handle){
    id
    title
    handle
    products(first:10) {
      edges {
        node {
          id
        }
      }
    }
  }
}

 

and 3. I was JSON.stringify-ing the axios data payload unnecessarily. Passing the data payload object directly without stringifying works.