{"record":{"id":"5687616419ebfbf3","repo":"louislam/uptime-kuma","slug":"only-allowed-png-logo","errorCode":null,"errorMessage":"Only allowed PNG logo.","messagePattern":"Only allowed PNG logo\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"server/socket-handlers/status-page-socket-handler.js","lineNumber":312,"sourceCode":"            checkLogin(socket);\n\n            // Save Config\n            let statusPage = await R.findOne(\"status_page\", \" slug = ? \", [slug]);\n\n            if (!statusPage) {\n                throw new Error(\"No slug?\");\n            }\n\n            checkSlug(config.slug);\n\n            const header = \"data:image/png;base64,\";\n\n            // Check logo format\n            // If is image data url, convert to png file\n            // Else assume it is a url, nothing to do\n            if (imgDataUrl.startsWith(\"data:\")) {\n                if (!imgDataUrl.startsWith(header)) {\n                    throw new Error(\"Only allowed PNG logo.\");\n                }\n\n                const filename = `logo${statusPage.id}.png`;\n\n                // Convert to file\n                await ImageDataURI.outputFile(imgDataUrl, Database.uploadDir + filename);\n                config.logo = `/upload/${filename}?t=` + Date.now();\n            } else {\n                config.logo = imgDataUrl;\n            }\n\n            statusPage.slug = config.slug;\n            statusPage.title = config.title;\n            statusPage.description = config.description;\n            statusPage.icon = config.logo;\n            ((statusPage.autoRefreshInterval = config.autoRefreshInterval), (statusPage.theme = config.theme));\n            //statusPage.published = ;\n            //statusPage.search_engine_index = ;","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/louislam/uptime-kuma/blob/6b5ea0155793e666666745fb8d6fef1e829543a2/server/socket-handlers/status-page-socket-handler.js#L294-L330","documentation":"Thrown by saveStatusPage when imgDataUrl starts with 'data:' but does not start with the PNG data-URL header 'data:image/png;base64,'. Only PNG logos are accepted because the saved file is hard-coded to logo<id>.png via ImageDataURI.outputFile.","triggerScenarios":"Client uploads a JPEG, GIF, SVG, or WebP image as a data URL for the status page logo; the data: prefix is present but the MIME is not image/png.","commonSituations":"User pastes/uploads a non-PNG logo; frontend does not pre-convert; browser produces image/jpeg for screenshots; SVG rejected for security.","solutions":["Convert the logo to PNG before sending (canvas toBlob('image/png') or an image tool).","If the image is hosted externally, pass a URL instead of a data: URL (the else branch treats it as a URL).","Reject non-PNG files in the client file picker before encoding to data URL."],"exampleFix":"// before\nsocket.emit(\"saveStatusPage\", slug, config, \"data:image/jpeg;base64,...\", groups, cb);\n// after\nsocket.emit(\"saveStatusPage\", slug, config, \"data:image/png;base64,...\", groups, cb);","handlingStrategy":"validation","validationCode":"const PNG_HEADER = \"data:image/png;base64,\";\nfunction encodeAsPng(file) { /* use canvas.toBlob('image/png') */ }\nif (imgDataUrl.startsWith(\"data:\") && !imgDataUrl.startsWith(PNG_HEADER)) {\n  imgDataUrl = await encodeAsPng(file);\n}\nsocket.emit(\"saveStatusPage\", slug, config, imgDataUrl, groups, cb);","typeGuard":"function isPngDataUrl(s) {\n  return typeof s === \"string\" && s.startsWith(\"data:image/png;base64,\");\n}","tryCatchPattern":"try { await emitAsync(\"saveStatusPage\", slug, config, img, groups, cb); }\ncatch (e) { if (/Only allowed PNG/.test(e.message)) convertAndRetry(); else throw e; }","preventionTips":["Accept only image/png in the file picker.","Convert non-PNG images to PNG before encoding.","Use a URL instead of a data URL for hosted logos."],"tags":["status-page","logo","image","validation","png","socket-io"],"backgroundTag":null,"analyzedSha":"6b5ea0155793e666666745fb8d6fef1e829543a2","analyzedAt":"2026-08-12T23:42:12.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}