{"record":{"id":"5ab89968a31f5593","repo":"RocketChat/Rocket.Chat","slug":"invalid-field-content","errorCode":"invalid-field-content","errorMessage":"invalid-field-content","messagePattern":"invalid-field-content","errorType":"exception","errorClass":"Meteor.Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/rooms.ts","lineNumber":298,"sourceCode":"\t\t\t\tfield: 'file',\n\t\t\t\tmaxSize: settings.get<number>('FileUpload_MaxFileSize'),\n\t\t\t});\n\n\t\t\tif (!file) {\n\t\t\t\tthrow new Meteor.Error('error-no-file-uploaded', 'No file was uploaded');\n\t\t\t}\n\n\t\t\tconst expiresAt = new Date();\n\t\t\texpiresAt.setHours(expiresAt.getHours() + 24);\n\n\t\t\tlet content;\n\n\t\t\tif (fields.content) {\n\t\t\t\ttry {\n\t\t\t\t\tcontent = JSON.parse(fields.content);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.error(e);\n\t\t\t\t\tthrow new Meteor.Error('invalid-field-content');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst details = {\n\t\t\t\tname: file.filename,\n\t\t\t\tsize: file.size,\n\t\t\t\ttype: file.mimetype,\n\t\t\t\trid: this.urlParams.rid,\n\t\t\t\tuserId: this.userId,\n\t\t\t\tcontent,\n\t\t\t\texpiresAt,\n\t\t\t};\n\n\t\t\t// TODO: In the future, we should isolate file receival from storage and post-processing.\n\t\t\tconst fileStore = FileUpload.getStore('Uploads');\n\t\t\tconst uploadedFile = await fileStore.insert(details, file.tempFilePath);\n\n\t\t\tuploadedFile.path = FileUpload.getPath(`${uploadedFile._id}/${encodeURI(uploadedFile.name || '')}`);","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/e4b8178b205510181a96ceefee043d0abcd13e5a/apps/meteor/server/api/v1/rooms.ts#L280-L316","documentation":"Thrown by POST /api/v1/rooms.media/:rid when the optional multipart field content is present but JSON.parse(fields.content) throws, meaning the field is not valid JSON. The code has no human-readable message, only the error code 'invalid-field-content'. The parsed value becomes the attachment message's content sent on to mediaConfirm.","triggerScenarios":"POST rooms.media with content appended as a raw object (FormData serializes it to '[object Object]'); single-quoted or trailing-comma JSON; content truncated by a proxy; concatenated JSON fragments.","commonSituations":"Clients appending structured payloads without JSON.stringify; template strings producing invalid JSON; content built from user input with unescaped quotes; partial uploads where the content part was cut off.","solutions":["Stringify before appending: form.append('content', JSON.stringify(obj))","Validate before upload: JSON.parse(content) must not throw on the client","Omit the content field entirely when no structured payload is needed"],"exampleFix":"// before\nform.append('content', { msg: 'see attachment', rid }); // '[object Object]' -> invalid-field-content\n\n// after\nform.append('content', JSON.stringify({ msg: 'see attachment', rid }));","handlingStrategy":"validation","validationCode":"let contentStr: string | undefined;\nif (content != null) {\n  contentStr = typeof content === 'string' ? content : JSON.stringify(content);\n  JSON.parse(contentStr); // throws locally before the server does\n}","typeGuard":null,"tryCatchPattern":"try {\n  form.append('content', contentStr);\n  await fetch(url, { method: 'POST', body: form });\n} catch (e: any) {\n  if (e?.response?.data?.errorType === 'invalid-field-content') {\n    form.set('content', JSON.stringify(safePayload)); // resend with serialized JSON\n  }\n  throw e;\n}","preventionTips":["JSON.stringify everything appended to the content field","Parse-validate generated JSON before upload","Omit content when there is no structured payload"],"tags":["rooms","file-upload","json","rest-api"],"backgroundTag":"invalid-json-payload","analyzedSha":"e4b8178b205510181a96ceefee043d0abcd13e5a","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}