{"record":{"id":"d4dc2b7fef65b538","repo":"RocketChat/Rocket.Chat","slug":"no-app-json-file-found-in-the-zip","errorCode":null,"errorMessage":"No app.json file found in the zip","messagePattern":"No app\\.json file found in the zip","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/meteor/client/views/marketplace/lib/getManifestFromZippedApp.ts","lineNumber":22,"sourceCode":"type Uint8ArrayObject = { [fileName: string]: Uint8Array };\ntype AppManifestSchema = { id: string; name: string; permissions: AppPermission[] };\n\nasync function fileToUint8Array(file: File): Promise<Uint8Array> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst fileReader = new FileReader();\n\t\tfileReader.onload = (e): void => resolve(new Uint8Array((e.target as any).result as Uint8Array));\n\t\tfileReader.onerror = (e): void => reject(e);\n\t\tfileReader.readAsArrayBuffer(file);\n\t});\n}\n\nfunction unzipAppBuffer(zippedAppBuffer: Uint8Array): Uint8ArrayObject {\n\treturn unzipSync(zippedAppBuffer);\n}\n\nfunction getAppManifest(unzippedAppBuffer: Uint8ArrayObject): AppManifestSchema {\n\tif (!unzippedAppBuffer['app.json']) {\n\t\tthrow new Error('No app.json file found in the zip');\n\t}\n\n\ttry {\n\t\treturn JSON.parse(strFromU8(unzippedAppBuffer['app.json']));\n\t} catch (e) {\n\t\tthrow new Error(`Failed to parse app.json: ${e instanceof Error ? e.message : String(e)}`);\n\t}\n}\n\nasync function unzipZippedApp(zippedApp: File | Uint8Array): Promise<Uint8ArrayObject> {\n\ttry {\n\t\tif (zippedApp instanceof File) {\n\t\t\tzippedApp = await fileToUint8Array(zippedApp);\n\t\t}\n\n\t\treturn unzipAppBuffer(zippedApp);\n\t} catch (e) {\n\t\tconsole.error(e);","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/client/views/marketplace/lib/getManifestFromZippedApp.ts#L4-L40","documentation":"Thrown by getAppManifest when the unzipped app archive does not contain an 'app.json' file at its root. The function unzips the app bundle (a zip archive) using unzipSync from the fflate library and checks for the 'app.json' key. Every Rocket.Chat app must have an app.json manifest at the zip root describing its name, version, classFile, and other metadata.","triggerScenarios":"The uploaded zip file is not a valid Rocket.Chat app archive. The app.json file exists but in a subdirectory instead of the zip root. The zip was created incorrectly (e.g., zipping a folder rather than its contents). A non-app zip file was uploaded by mistake.","commonSituations":"Developer zips the project folder (creating folder/app.json instead of app.json at root). User uploads the wrong file (e.g., a theme or asset zip). App build process changed and no longer includes app.json at root. Corrupted or truncated zip file.","solutions":["Ensure app.json is at the root of the zip archive, not inside a subdirectory. Zip the contents, not the parent folder.","Verify the zip is a valid Rocket.Chat app by checking its structure before uploading.","Use the app build tool (rc-apps) which correctly packages the app with app.json at root.","If unzipping from a File object, ensure it was read correctly as an ArrayBuffer/Uint8Array."],"exampleFix":"# before: zips the folder, creating myapp/app.json\ncd parent && zip -r myapp.zip myapp/\n# after: zip from inside the app directory so app.json is at root\ncd myapp && zip -r ../myapp.zip .","handlingStrategy":"validation","validationCode":"const entries = Object.keys(unzippedAppBuffer);\nif (!entries.includes('app.json')) {\n  throw new Error('This zip is not a valid Rocket.Chat app: missing app.json at root');\n}","typeGuard":"const hasAppJsonAtRoot = (entries: string[]): boolean =>\n  entries.includes('app.json');","tryCatchPattern":"try {\n  const manifest = await getManifestFromZippedApp(zipFile);\n} catch (e) {\n  if (e instanceof Error && e.message === 'No app.json file found in the zip') {\n    showInvalidAppError();\n    return;\n  }\n  throw e;\n}","preventionTips":["Always build apps with the rc-apps CLI tool which correctly packages app.json at the zip root.","When zipping manually, zip the contents of the app directory, not the directory itself.","Validate the zip structure before attempting to install.","Provide clear user-facing errors when app installation fails."],"tags":["app-engine","marketplace","zip","manifest","validation","file-parsing"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}