SillyTavern/SillyTavern · warning

Only JSON workflow files are allowed

Error message

Only JSON workflow files are allowed

What it means

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.

Source

Thrown at src/endpoints/stable-diffusion.js:540

    try {
        const filePath = path.join(request.user.directories.comfyWorkflows, sanitize(String(request.body.file_name)));
        if (fs.existsSync(filePath)) {
            fs.unlinkSync(filePath);
        }
        return response.sendStatus(200);
    } catch (error) {
        console.error(error);
        return response.sendStatus(500);
    }
});

comfy.post('/rename-workflow', getFileNameValidationFunction('old_name'), getFileNameValidationFunction('new_name'), async (request, response) => {
    try {
        const oldName = sanitize(String(request.body.old_name));
        const newName = sanitize(String(request.body.new_name));

        if (path.extname(oldName).toLowerCase() !== '.json' || path.extname(newName).toLowerCase() !== '.json') {
            return response.status(400).send('Only JSON workflow files are allowed');
        }

        const oldPath = path.join(request.user.directories.comfyWorkflows, oldName);
        const newPath = path.join(request.user.directories.comfyWorkflows, newName);

        if (!fs.existsSync(oldPath)) {
            return response.status(404).send('Workflow not found');
        }

        if (fs.existsSync(newPath)) {
            return response.status(409).send('A workflow with that name already exists');
        }

        fs.renameSync(oldPath, newPath);
        return response.sendStatus(204);
    } catch (error) {
        console.error('ComfyUI workflow rename failed', error);
        return response.sendStatus(500);

View on GitHub (pinned to 8172dcd0ee)

Solutions

  1. Append '.json' to both old_name and new_name before posting if not already present.
  2. In the UI, force the new name field to end with .json on submit (strip then re-add).
  3. Validate extensions client-side and disable submit until both are .json.

Example fix

// before
body: JSON.stringify({ old_name: 'workflow', new_name: 'workflow-v2' })
// after
const ensureJson = n => n.toLowerCase().endsWith('.json') ? n : n + '.json';
body: JSON.stringify({ old_name: ensureJson('workflow'), new_name: ensureJson('workflow-v2') })
Defensive patterns

Strategy: validation

Validate before calling

function ensureJsonExt(name) {
  return String(name).toLowerCase().endsWith('.json') ? String(name) : String(name) + '.json';
}

Type guard

/** @param {unknown} n */
const isJsonWorkflowName = (n) => typeof n === 'string' && n.toLowerCase().endsWith('.json');

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of SillyTavern/SillyTavern@8172dcd0ee (2026-08-13). Data as JSON: /api/errors/de0850b5279e4792. Report an issue: GitHub.