{"record":{"id":"c29b5bbf1268ae91","repo":"lllyasviel/Fooocus","slug":"error-saving-image-outside-the-output-folder","errorCode":null,"errorMessage":"**** ERROR: Saving image outside the output folder is not allowed.","messagePattern":"\\*\\*\\*\\* ERROR: Saving image outside the output folder is not allowed\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"ldm_patched/utils/path_utils.py","lineNumber":253,"sourceCode":"    def compute_vars(input, image_width, image_height):\n        input = input.replace(\"%width%\", str(image_width))\n        input = input.replace(\"%height%\", str(image_height))\n        return input\n\n    filename_prefix = compute_vars(filename_prefix, image_width, image_height)\n\n    subfolder = os.path.dirname(os.path.normpath(filename_prefix))\n    filename = os.path.basename(os.path.normpath(filename_prefix))\n\n    full_output_folder = os.path.join(output_dir, subfolder)\n\n    if os.path.commonpath((output_dir, os.path.abspath(full_output_folder))) != output_dir:\n        err = \"**** ERROR: Saving image outside the output folder is not allowed.\" + \\\n              \"\\n full_output_folder: \" + os.path.abspath(full_output_folder) + \\\n              \"\\n         output_dir: \" + output_dir + \\\n              \"\\n         commonpath: \" + os.path.commonpath((output_dir, os.path.abspath(full_output_folder))) \n        print(err)\n        raise Exception(err)\n\n    try:\n        counter = max(filter(lambda a: a[1][:-1] == filename and a[1][-1] == \"_\", map(map_filename, os.listdir(full_output_folder))))[0] + 1\n    except ValueError:\n        counter = 1\n    except FileNotFoundError:\n        os.makedirs(full_output_folder, exist_ok=True)\n        counter = 1\n    return full_output_folder, filename, counter, subfolder, filename_prefix\n","sourceCodeStart":235,"sourceCodeEnd":263,"githubUrl":"https://github.com/lllyasviel/Fooocus/blob/ae05379cc97bc4361ec8b4ec90193dab21be763f/ldm_patched/utils/path_utils.py#L235-L263","documentation":"save_image's timestamped-filename helper (ldm_patched/utils/path_utils.py) refuses to write outside the designated output folder: it joins output_dir with the subfolder taken from filename_prefix and verifies via os.path.commonpath that the resolved path is still inside output_dir. If filename_prefix contains '..' segments (or an absolute-path trick) that escapes, it prints a diagnostic and raises a bare Exception. This is a path-traversal guard for image saving.","triggerScenarios":"Passing filename_prefix like '../foo/img', '/etc/passwd/img', or a subfolder that normalizes above output_dir; also triggered when output_dir is a relative path and the prefix resolves to a sibling directory.","commonSituations":"Automating Fooocus via its API with a caller-supplied filename_prefix; using wildcard/path templates that include '..' on Windows (where path joining differs); symlinked output folders that break the commonpath comparison.","solutions":["Strip traversal segments from the prefix: keep only os.path.basename components, or normalize and reject '..' before calling save_image.","Pass a plain filename (e.g. 'Fooocus/img_001') and let the function build the subfolder under output_dir.","Read the printed diagnostic (it shows full_output_folder vs output_dir vs commonpath) to see exactly which prefix component escaped."],"exampleFix":"# before\nsave_image(images, output_dir, '../../shared/img', ...)\n# after\nprefix = os.path.basename('../../shared/img')  # -> 'img'\nsave_image(images, output_dir, prefix, ...)","handlingStrategy":"validation","validationCode":"import os\nsafe = not os.path.isabs(filename_prefix) and '..' not in os.path.normpath(filename_prefix).split(os.sep)\nif not safe:\n    filename_prefix = os.path.basename(filename_prefix)\n# strongest guarantee: resolved target must stay under output_dir\ntarget = os.path.abspath(os.path.join(output_dir, os.path.dirname(os.path.normpath(filename_prefix))))\nassert os.path.commonpath((output_dir, target)) == output_dir","typeGuard":"def is_safe_prefix(output_dir: str, prefix: str) -> bool:\n    p = os.path.normpath(prefix)\n    if os.path.isabs(p) or p.startswith('..'):\n        return False\n    target = os.path.abspath(os.path.join(output_dir, p))\n    return os.path.commonpath((output_dir, target)) == output_dir","tryCatchPattern":"try:\n    save_image(img, output_dir, prefix, ...)\nexcept Exception as e:\n    if 'outside the output folder' in str(e):\n        prefix = os.path.basename(prefix)  # retry with sanitized prefix\n        save_image(img, output_dir, prefix, ...)\n    else:\n        raise","preventionTips":["Treat any caller-supplied filename_prefix as untrusted: whitelist [A-Za-z0-9_./-] and drop '..' segments.","Prefer bare filenames/subfolder names like 'Fooocus/run_01' and let the util construct the full path."],"tags":["security","path-traversal","filesystem","image-saving","sanitization"],"backgroundTag":null,"analyzedSha":"ae05379cc97bc4361ec8b4ec90193dab21be763f","analyzedAt":"2026-08-15T04:23:59.533Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}