Skip to main content
Visitor II
March 19, 2024
Solved

PayloadTooLargeError: request entity too large

  • March 19, 2024
  • 3 replies
  • 7069 views

Hi, please can someone help me?
when I try to deploy I get the following error:

Spoiler
PayloadTooLargeError: request entity too large
at readStream (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\raw-body\index.js:163:17)
at getRawBody (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\raw-body\index.js:116:12)
at read (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\body-parser\lib\read.js:79:3)
at jsonParser (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\body-parser\lib\types\json.js:138:5)
at Layer.handle [as handle_request] (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\express\lib\router\index.js:328:13)
at C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\express\lib\router\index.js:286:9
at Function.process_params (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\express\lib\router\index.js:346:12)
at next (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\express\lib\router\index.js:280:10)
at cors (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\cors\lib\index.js:188:7)

The file.elf that I upload is 1930Kb, if I upload a file.elf of smaller dimensions the error does not exist.

 

 

    This topic has been closed for replies.
    Best answer by Mavi

    I managed to solve the problem, I'll post the solution if it helps others...
    in this file: "C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\body-parser\lib\types\json.js"
    I changed the "limit" variable as follows:

    function json (options) {
     var opts = options || {}
     //****** OLD *********
     //var limit = typeof opts.limit !== 'number'
     // ? bytes.parse(opts.limit || '100kb')
     // : opts.limit
     //******* NEW ********
     var limit = bytes.parse('10Mb')
     var inflate = opts.inflate !== false
     var reviver = opts.reviver
     var strict = opts.strict !== false
     var type = opts.type || 'application/json'
     var verify = opts.verify || false
    .....
    ....
    }

    3 replies

    Super User
    March 19, 2024

    at readStream (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\raw-body\index.js:163:17)

    > at getRawBody (C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\raw-body\index.js:116:12)

    Please look in these files and see what is the size limit there? Is this a hardcoded limit in the script, or inconsistency/corruption in the data?

     

    MaviAuthor
    Visitor II
    March 20, 2024

    I'm sorry, I'm not a javascript expert, but it seems that the limit is passed to him as an argument... it's not defined in these files or am I wrong?

    C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\raw-body\index.js:163:17

    Spoiler
    /*!
     * raw-body
     * Copyright(c) 2013-2014 Jonathan Ong
     * Copyright(c) 2014-2022 Douglas Christopher Wilson
     * MIT Licensed
     */
    
    'use strict'
    
    /**
     * Module dependencies.
     * @private
     */
    
    var asyncHooks = tryRequireAsyncHooks()
    var bytes = require('bytes')
    var createError = require('http-errors')
    var iconv = require('iconv-lite')
    var unpipe = require('unpipe')
    
    /**
     * Module exports.
     * @public
     */
    
    module.exports = getRawBody
    
    /**
     * Module variables.
     * @private
     */
    
    var ICONV_ENCODING_MESSAGE_REGEXP = /^Encoding not recognized: /
    
    /**
     * Get the decoder for a given encoding.
     *
     * @PAram {string} encoding
     * @private
     */
    
    function getDecoder (encoding) {
     if (!encoding) return null
    
     try {
     return iconv.getDecoder(encoding)
     } catch (e) {
     // error getting decoder
     if (!ICONV_ENCODING_MESSAGE_REGEXP.test(e.message)) throw e
    
     // the encoding was not found
     throw createError(415, 'specified encoding unsupported', {
     encoding: encoding,
     type: 'encoding.unsupported'
     })
     }
    }
    
    /**
     * Get the raw body of a stream (typically HTTP).
     *
     * @PAram {object} stream
     * @PAram {object|string|function} [options]
     * @PAram {function} [callback]
     * @public
     */
    
    function getRawBody (stream, options, callback) {
     var done = callback
     var opts = options || {}
    
     // light validation
     if (stream === undefined) {
     throw new TypeError('argument stream is required')
     } else if (typeof stream !== 'object' || stream === null || typeof stream.on !== 'function') {
     throw new TypeError('argument stream must be a stream')
     }
    
     if (options === true || typeof options === 'string') {
     // short cut for encoding
     opts = {
     encoding: options
     }
     }
    
     if (typeof options === 'function') {
     done = options
     opts = {}
     }
    
     // validate callback is a function, if provided
     if (done !== undefined && typeof done !== 'function') {
     throw new TypeError('argument callback must be a function')
     }
    
     // require the callback without promises
     if (!done && !global.Promise) {
     throw new TypeError('argument callback is required')
     }
    
     // get encoding
     var encoding = opts.encoding !== true
     ? opts.encoding
     : 'utf-8'
    
     // convert the limit to an integer
     var limit = bytes.parse(opts.limit)
    
     // convert the expected length to an integer
     var length = opts.length != null && !isNaN(opts.length)
     ? parseInt(opts.length, 10)
     : null
    
     if (done) {
     // classic callback style
     return readStream(stream, encoding, length, limit, wrap(done))
     }
    
     return new Promise(function executor (resolve, reject) {
     readStream(stream, encoding, length, limit, function onRead (err, buf) {
     if (err) return reject(err)
     resolve(buf)
     })
     })
    }
    
    /**
     * Halt a stream.
     *
     * @PAram {Object} stream
     * @private
     */
    
    function halt (stream) {
     // unpipe everything from the stream
     unpipe(stream)
    
     // pause stream
     if (typeof stream.pause === 'function') {
     stream.pause()
     }
    }
    
    /**
     * Read the data from the stream.
     *
     * @PAram {object} stream
     * @PAram {string} encoding
     * @PAram {number} length
     * @PAram {number} limit
     * @PAram {function} callback
     * @public
     */
    
    function readStream (stream, encoding, length, limit, callback) {
     var complete = false
     var sync = true
    
     // check the length and limit options.
     // note: we intentionally leave the stream paused,
     // so users should handle the stream themselves.
     if (limit !== null && length !== null && length > limit) {
     return done(createError(413, 'request entity too large', {
     expected: length,
     length: length,
     limit: limit,
     type: 'entity.too.large'
     }))
     }
    
     // streams1: assert request encoding is buffer.
     // streams2+: assert the stream encoding is buffer.
     // stream._decoder: streams1
     // state.encoding: streams2
     // state.decoder: streams2, specifically < 0.10.6
     var state = stream._readableState
     if (stream._decoder || (state && (state.encoding || state.decoder))) {
     // developer error
     return done(createError(500, 'stream encoding should not be set', {
     type: 'stream.encoding.set'
     }))
     }
    
     if (typeof stream.readable !== 'undefined' && !stream.readable) {
     return done(createError(500, 'stream is not readable', {
     type: 'stream.not.readable'
     }))
     }
    
     var received = 0
     var decoder
    
     try {
     decoder = getDecoder(encoding)
     } catch (err) {
     return done(err)
     }
    
     var buffer = decoder
     ? ''
     : []
    
     // attach listeners
     stream.on('aborted', onAborted)
     stream.on('close', cleanup)
     stream.on('data', onData)
     stream.on('end', onEnd)
     stream.on('error', onEnd)
    
     // mark sync section complete
     sync = false
    
     function done () {
     var args = new Array(arguments.length)
    
     // copy arguments
     for (var i = 0; i < args.length; i++) {
     args[i] = arguments[i]
     }
    
     // mark complete
     complete = true
    
     if (sync) {
     process.nextTick(invokeCallback)
     } else {
     invokeCallback()
     }
    
     function invokeCallback () {
     cleanup()
    
     if (args[0]) {
     // halt the stream on error
     halt(stream)
     }
    
     callback.apply(null, args)
     }
     }
    
     function onAborted () {
     if (complete) return
    
     done(createError(400, 'request aborted', {
     code: 'ECONNABORTED',
     expected: length,
     length: length,
     received: received,
     type: 'request.aborted'
     }))
     }
    
     function onData (chunk) {
     if (complete) return
    
     received += chunk.length
    
     if (limit !== null && received > limit) {
     done(createError(413, 'request entity too large', {
     limit: limit,
     received: received,
     type: 'entity.too.large'
     }))
     } else if (decoder) {
     buffer += decoder.write(chunk)
     } else {
     buffer.push(chunk)
     }
     }
    
     function onEnd (err) {
     if (complete) return
     if (err) return done(err)
    
     if (length !== null && received !== length) {
     done(createError(400, 'request size did not match content length', {
     expected: length,
     length: length,
     received: received,
     type: 'request.size.invalid'
     }))
     } else {
     var string = decoder
     ? buffer + (decoder.end() || '')
     : Buffer.concat(buffer)
     done(null, string)
     }
     }
    
     function cleanup () {
     buffer = null
    
     stream.removeListener('aborted', onAborted)
     stream.removeListener('data', onData)
     stream.removeListener('end', onEnd)
     stream.removeListener('error', onEnd)
     stream.removeListener('close', cleanup)
     }
    }
    
    /**
     * Try to require async_hooks
     * @private
     */
    
    function tryRequireAsyncHooks () {
     try {
     return require('async_hooks')
     } catch (e) {
     return {}
     }
    }
    
    /**
     * Wrap function with async resource, if possible.
     * AsyncResource.bind static method backported.
     * @private
     */
    
    function wrap (fn) {
     var res
    
     // create anonymous resource
     if (asyncHooks.AsyncResource) {
     res = new asyncHooks.AsyncResource(fn.name || 'bound-anonymous-fn')
     }
    
     // incompatible node.js
     if (!res || !res.runInAsyncScope) {
     return fn
     }
    
     // return bound function
     return res.runInAsyncScope.bind(res, fn, null)
    }

    C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\raw-body\index.js:116:12

    Spoiler
    /*!
     * raw-body
     * Copyright(c) 2013-2014 Jonathan Ong
     * Copyright(c) 2014-2022 Douglas Christopher Wilson
     * MIT Licensed
     */
    
    'use strict'
    
    /**
     * Module dependencies.
     * @private
     */
    
    var asyncHooks = tryRequireAsyncHooks()
    var bytes = require('bytes')
    var createError = require('http-errors')
    var iconv = require('iconv-lite')
    var unpipe = require('unpipe')
    
    /**
     * Module exports.
     * @public
     */
    
    module.exports = getRawBody
    
    /**
     * Module variables.
     * @private
     */
    
    var ICONV_ENCODING_MESSAGE_REGEXP = /^Encoding not recognized: /
    
    /**
     * Get the decoder for a given encoding.
     *
     * @PAram {string} encoding
     * @private
     */
    
    function getDecoder (encoding) {
     if (!encoding) return null
    
     try {
     return iconv.getDecoder(encoding)
     } catch (e) {
     // error getting decoder
     if (!ICONV_ENCODING_MESSAGE_REGEXP.test(e.message)) throw e
    
     // the encoding was not found
     throw createError(415, 'specified encoding unsupported', {
     encoding: encoding,
     type: 'encoding.unsupported'
     })
     }
    }
    
    /**
     * Get the raw body of a stream (typically HTTP).
     *
     * @PAram {object} stream
     * @PAram {object|string|function} [options]
     * @PAram {function} [callback]
     * @public
     */
    
    function getRawBody (stream, options, callback) {
     var done = callback
     var opts = options || {}
    
     // light validation
     if (stream === undefined) {
     throw new TypeError('argument stream is required')
     } else if (typeof stream !== 'object' || stream === null || typeof stream.on !== 'function') {
     throw new TypeError('argument stream must be a stream')
     }
    
     if (options === true || typeof options === 'string') {
     // short cut for encoding
     opts = {
     encoding: options
     }
     }
    
     if (typeof options === 'function') {
     done = options
     opts = {}
     }
    
     // validate callback is a function, if provided
     if (done !== undefined && typeof done !== 'function') {
     throw new TypeError('argument callback must be a function')
     }
    
     // require the callback without promises
     if (!done && !global.Promise) {
     throw new TypeError('argument callback is required')
     }
    
     // get encoding
     var encoding = opts.encoding !== true
     ? opts.encoding
     : 'utf-8'
    
     // convert the limit to an integer
     var limit = bytes.parse(opts.limit)
    
     // convert the expected length to an integer
     var length = opts.length != null && !isNaN(opts.length)
     ? parseInt(opts.length, 10)
     : null
    
     if (done) {
     // classic callback style
     return readStream(stream, encoding, length, limit, wrap(done))
     }
    
     return new Promise(function executor (resolve, reject) {
     readStream(stream, encoding, length, limit, function onRead (err, buf) {
     if (err) return reject(err)
     resolve(buf)
     })
     })
    }
    
    /**
     * Halt a stream.
     *
     * @PAram {Object} stream
     * @private
     */
    
    function halt (stream) {
     // unpipe everything from the stream
     unpipe(stream)
    
     // pause stream
     if (typeof stream.pause === 'function') {
     stream.pause()
     }
    }
    
    /**
     * Read the data from the stream.
     *
     * @PAram {object} stream
     * @PAram {string} encoding
     * @PAram {number} length
     * @PAram {number} limit
     * @PAram {function} callback
     * @public
     */
    
    function readStream (stream, encoding, length, limit, callback) {
     var complete = false
     var sync = true
    
     // check the length and limit options.
     // note: we intentionally leave the stream paused,
     // so users should handle the stream themselves.
     if (limit !== null && length !== null && length > limit) {
     return done(createError(413, 'request entity too large', {
     expected: length,
     length: length,
     limit: limit,
     type: 'entity.too.large'
     }))
     }
    
     // streams1: assert request encoding is buffer.
     // streams2+: assert the stream encoding is buffer.
     // stream._decoder: streams1
     // state.encoding: streams2
     // state.decoder: streams2, specifically < 0.10.6
     var state = stream._readableState
     if (stream._decoder || (state && (state.encoding || state.decoder))) {
     // developer error
     return done(createError(500, 'stream encoding should not be set', {
     type: 'stream.encoding.set'
     }))
     }
    
     if (typeof stream.readable !== 'undefined' && !stream.readable) {
     return done(createError(500, 'stream is not readable', {
     type: 'stream.not.readable'
     }))
     }
    
     var received = 0
     var decoder
    
     try {
     decoder = getDecoder(encoding)
     } catch (err) {
     return done(err)
     }
    
     var buffer = decoder
     ? ''
     : []
    
     // attach listeners
     stream.on('aborted', onAborted)
     stream.on('close', cleanup)
     stream.on('data', onData)
     stream.on('end', onEnd)
     stream.on('error', onEnd)
    
     // mark sync section complete
     sync = false
    
     function done () {
     var args = new Array(arguments.length)
    
     // copy arguments
     for (var i = 0; i < args.length; i++) {
     args[i] = arguments[i]
     }
    
     // mark complete
     complete = true
    
     if (sync) {
     process.nextTick(invokeCallback)
     } else {
     invokeCallback()
     }
    
     function invokeCallback () {
     cleanup()
    
     if (args[0]) {
     // halt the stream on error
     halt(stream)
     }
    
     callback.apply(null, args)
     }
     }
    
     function onAborted () {
     if (complete) return
    
     done(createError(400, 'request aborted', {
     code: 'ECONNABORTED',
     expected: length,
     length: length,
     received: received,
     type: 'request.aborted'
     }))
     }
    
     function onData (chunk) {
     if (complete) return
    
     received += chunk.length
    
     if (limit !== null && received > limit) {
     done(createError(413, 'request entity too large', {
     limit: limit,
     received: received,
     type: 'entity.too.large'
     }))
     } else if (decoder) {
     buffer += decoder.write(chunk)
     } else {
     buffer.push(chunk)
     }
     }
    
     function onEnd (err) {
     if (complete) return
     if (err) return done(err)
    
     if (length !== null && received !== length) {
     done(createError(400, 'request size did not match content length', {
     expected: length,
     length: length,
     received: received,
     type: 'request.size.invalid'
     }))
     } else {
     var string = decoder
     ? buffer + (decoder.end() || '')
     : Buffer.concat(buffer)
     done(null, string)
     }
     }
    
     function cleanup () {
     buffer = null
    
     stream.removeListener('aborted', onAborted)
     stream.removeListener('data', onData)
     stream.removeListener('end', onEnd)
     stream.removeListener('error', onEnd)
     stream.removeListener('close', cleanup)
     }
    }
    
    /**
     * Try to require async_hooks
     * @private
     */
    
    function tryRequireAsyncHooks () {
     try {
     return require('async_hooks')
     } catch (e) {
     return {}
     }
    }
    
    /**
     * Wrap function with async resource, if possible.
     * AsyncResource.bind static method backported.
     * @private
     */
    
    function wrap (fn) {
     var res
    
     // create anonymous resource
     if (asyncHooks.AsyncResource) {
     res = new asyncHooks.AsyncResource(fn.name || 'bound-anonymous-fn')
     }
    
     // incompatible node.js
     if (!res || !res.runInAsyncScope) {
     return fn
     }
    
     // return bound function
     return res.runInAsyncScope.bind(res, fn, null)
    }

    I noticed that in the "exe-config node" if I select "expand variable list" the deployment gives an error while if I don't select it it proceeds normally...
    If I export my "Flow" with the complete variable list I get a.json file containing the entire list of variables, not just those selected by me... Perhaps I exceed the "exevariablelist" limit

    export_json_file.png

     

    MaviAuthorAnswer
    Visitor II
    March 20, 2024

    I managed to solve the problem, I'll post the solution if it helps others...
    in this file: "C:\Users\diego.mavillonio\AppData\Local\STM32CubeMonitor\resources\app\node_modules\body-parser\lib\types\json.js"
    I changed the "limit" variable as follows:

    function json (options) {
     var opts = options || {}
     //****** OLD *********
     //var limit = typeof opts.limit !== 'number'
     // ? bytes.parse(opts.limit || '100kb')
     // : opts.limit
     //******* NEW ********
     var limit = bytes.parse('10Mb')
     var inflate = opts.inflate !== false
     var reviver = opts.reviver
     var strict = opts.strict !== false
     var type = opts.type || 'application/json'
     var verify = opts.verify || false
    .....
    ....
    }
    Visitor II
    October 2, 2024

    A cleaner solution would be to edit the settings file in the user folder:

    C:\Users\<userame>\.STMicroelectronics\stm32cubemonitor\settings.js

     /** The maximum size of HTTP request that will be accepted by the runtime api.
     * Default: 5mb
     */
     //apiMaxLength: '5mb',
     apiMaxLength: '10mb',
    

    This way the settings should be preserved after application updates.

    ST Employee
    December 15, 2025

    Hello

    With STM32CubeMonitor version 1.11.0 and after, the json.js file modification is not possible.

    The solution is to change the apiMaxLength in settings.js  ( pdematteis solution above)

    Stephane