{"record":{"id":"a08160cea6edb9a5","repo":"deepfakes/faceswap","slug":"the-output-location-must-be-a-string-not-a-type-s","errorCode":null,"errorMessage":"The output location must be a string not a {type(self.location)}","messagePattern":"The output location must be a string not a (.+?)","errorType":"exception","errorClass":"FaceswapError","httpStatus":null,"severity":"error","filePath":"lib/image.py","lineNumber":1300,"sourceCode":"    >>>     saver.save(filename, image)\n    >>> saver.close()\n    \"\"\"\n\n    def __init__(self, path, queue_size=8, as_bytes=False):\n        logger.debug(parse_class_init(locals()))\n        super().__init__(path, queue_size=queue_size)\n        self._as_bytes = as_bytes\n\n    def _check_location_exists(self):\n        \"\"\" Check whether the output location exists and is a folder\n\n        Raises\n        ------\n        FaceswapError\n            If the given location does not exist or the location is not a folder\n        \"\"\"\n        if not isinstance(self.location, str):\n            raise FaceswapError(\"The output location must be a string not a \"\n                                f\"{type(self.location)}\")\n        super()._check_location_exists()\n        if not os.path.isdir(self.location):\n            raise FaceswapError(f\"The output location '{self.location}' is not a folder\")\n\n    def _process(self, queue):\n        \"\"\" Saves images from the save queue to the given :attr:`location` inside a thread.\n\n        Parameters\n        ----------\n        queue: queue.Queue()\n            The ImageIO Queue\n        \"\"\"\n        executor = futures.ThreadPoolExecutor(thread_name_prefix=self.__class__.__name__)\n        assert self._error_state is not None\n        while True:\n            if self._error_state.has_error:\n                logger.debug(\"[%s] Thread error detected in worker thread\", self._name)","sourceCodeStart":1282,"sourceCodeEnd":1318,"githubUrl":"https://github.com/deepfakes/faceswap/blob/f530cb7508ae670f6474f8a7d9c4df94705cf96b/lib/image.py#L1282-L1318","documentation":"ImagesSaver overrides _check_location_exists and requires the output location to be a string (a single folder path). Passing a list/tuple of destinations, None, or a Path-like object raises this FaceswapError before the superclass existence check runs.","triggerScenarios":"Constructing ImagesSaver with a list of output folders (only one folder is supported), with None because a config variable was unset, or with pathlib.Path on versions expecting str.","commonSituations":"Reusing an input list for the output argument; config parsing that yields None; scripts building output paths programmatically and passing a non-string.","solutions":["Pass a single string folder path to ImagesSaver.","Default unset config values to a concrete string output folder.","Wrap Path objects with str(...) if using pathlib."],"exampleFix":"# before\n saver = ImagesSaver(['/out/a', '/out/b'])  # FaceswapError\n\n# after\nsaver = ImagesSaver('/out/a')  # one output folder only","handlingStrategy":"type-guard","validationCode":"if not isinstance(output_location, str) or not output_location:\n    raise SystemExit('output location must be a non-empty string folder path')","typeGuard":"def is_valid_output_location(loc) -> bool:\n    return isinstance(loc, str) and len(loc) > 0","tryCatchPattern":"try:\n    saver = ImagesSaver(loc)\nexcept FaceswapError as err:\n    if 'must be a string' in str(err):\n        loc = str(loc[0]) if isinstance(loc, (list, tuple)) else str(loc)\n        saver = ImagesSaver(loc)\n    else:\n        raise","preventionTips":["Normalize config-sourced output paths to str early.","Default None output configs to a concrete folder string.","Remember ImagesSaver takes exactly one folder, never a list."],"tags":["filesystem","type-error","validation","config"],"backgroundTag":null,"analyzedSha":"f530cb7508ae670f6474f8a7d9c4df94705cf96b","analyzedAt":"2026-08-15T02:59:26.626Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}