{"record":{"id":"de0850b5279e4792","repo":"SillyTavern/SillyTavern","slug":"only-json-workflow-files-are-allowed","errorCode":null,"errorMessage":"Only JSON workflow files are allowed","messagePattern":"Only JSON workflow files are allowed","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"src/endpoints/stable-diffusion.js","lineNumber":540,"sourceCode":"    try {\n        const filePath = path.join(request.user.directories.comfyWorkflows, sanitize(String(request.body.file_name)));\n        if (fs.existsSync(filePath)) {\n            fs.unlinkSync(filePath);\n        }\n        return response.sendStatus(200);\n    } catch (error) {\n        console.error(error);\n        return response.sendStatus(500);\n    }\n});\n\ncomfy.post('/rename-workflow', getFileNameValidationFunction('old_name'), getFileNameValidationFunction('new_name'), async (request, response) => {\n    try {\n        const oldName = sanitize(String(request.body.old_name));\n        const newName = sanitize(String(request.body.new_name));\n\n        if (path.extname(oldName).toLowerCase() !== '.json' || path.extname(newName).toLowerCase() !== '.json') {\n            return response.status(400).send('Only JSON workflow files are allowed');\n        }\n\n        const oldPath = path.join(request.user.directories.comfyWorkflows, oldName);\n        const newPath = path.join(request.user.directories.comfyWorkflows, newName);\n\n        if (!fs.existsSync(oldPath)) {\n            return response.status(404).send('Workflow not found');\n        }\n\n        if (fs.existsSync(newPath)) {\n            return response.status(409).send('A workflow with that name already exists');\n        }\n\n        fs.renameSync(oldPath, newPath);\n        return response.sendStatus(204);\n    } catch (error) {\n        console.error('ComfyUI workflow rename failed', error);\n        return response.sendStatus(500);","sourceCodeStart":522,"sourceCodeEnd":558,"githubUrl":"https://github.com/SillyTavern/SillyTavern/blob/8172dcd0ee672d3cd9a5e5f7af134f91a45cd2b8/src/endpoints/stable-diffusion.js#L522-L558","documentation":"HTTP 400 from POST /api/comfy/rename-workflow when either old_name or new_name has a path.extname that is not lower-case '.json'. The route is meant to manage ComfyUI workflow definition files, which are JSON; any other extension is rejected before filesystem paths are built.","triggerScenarios":"Client sends old_name='workflow' (no extension), new_name='workflow.txt', names with uppercase '.JSON' that lower-case correctly pass but '.yaml'/.png' do not, or a UI bug that strips the extension before submitting.","commonSituations":"Frontend text input that does not auto-append .json; user typing a custom name without extension; migrating workflow files saved without extension; paste of a filename that lost its extension.","solutions":["Append '.json' to both old_name and new_name before posting if not already present.","In the UI, force the new name field to end with .json on submit (strip then re-add).","Validate extensions client-side and disable submit until both are .json."],"exampleFix":"// before\nbody: JSON.stringify({ old_name: 'workflow', new_name: 'workflow-v2' })\n// after\nconst ensureJson = n => n.toLowerCase().endsWith('.json') ? n : n + '.json';\nbody: JSON.stringify({ old_name: ensureJson('workflow'), new_name: ensureJson('workflow-v2') })","handlingStrategy":"validation","validationCode":"function ensureJsonExt(name) {\n  return String(name).toLowerCase().endsWith('.json') ? String(name) : String(name) + '.json';\n}","typeGuard":"/** @param {unknown} n */\nconst isJsonWorkflowName = (n) => typeof n === 'string' && n.toLowerCase().endsWith('.json');","tryCatchPattern":null,"preventionTips":["Force the new-name input to end with .json on the client before enabling submit.","Reuse the same extension-normalization helper on both client and server."],"tags":["comfyui","validation","http-400","express","workflow"],"backgroundTag":null,"analyzedSha":"8172dcd0ee672d3cd9a5e5f7af134f91a45cd2b8","analyzedAt":"2026-08-13T07:48:40.832Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}