{"record":{"id":"e243a3e8460da9ce","repo":"invoke-ai/InvokeAI","slug":"unknown-image-subfolder-strategy-strategy","errorCode":null,"errorMessage":"Unknown image subfolder strategy: {strategy}","messagePattern":"Unknown image subfolder strategy: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"invokeai/app/services/image_moves/image_moves_default.py","lineNumber":745,"sourceCode":"            return None\n        return ImageMoveJob(\n            id=cast(int, row[\"id\"]), state=cast(MoveJobState, row[\"state\"]), error_message=row[\"error_message\"]\n        )\n\n    def _get_new_subfolder(\n        self, image_name: str, image_category: ImageCategory, is_intermediate: bool, created_at: str | datetime\n    ) -> str:\n        strategy = self._config.image_subfolder_strategy\n        if strategy == \"flat\":\n            return \"\"\n        if strategy == \"type\":\n            return \"intermediate\" if is_intermediate else image_category.value\n        if strategy == \"hash\":\n            return image_name[:2]\n        if strategy == \"date\":\n            timestamp = created_at if isinstance(created_at, datetime) else datetime.fromisoformat(created_at)\n            return f\"{timestamp.year}/{timestamp.month:02d}/{timestamp.day:02d}\"\n        raise ValueError(f\"Unknown image subfolder strategy: {strategy}\")\n\n    def _get_items(self, job_id: int, include_terminal: bool = True) -> list[PlannedImageMove]:\n        with self._db.transaction() as cursor:\n            query = \"\"\"--sql\n                SELECT image_name, old_subfolder, new_subfolder, is_intermediate\n                FROM image_subfolder_move_items\n                WHERE job_id = ?\n            \"\"\"\n            params: tuple[object, ...] = (job_id,)\n            if not include_terminal:\n                query += \" AND state NOT IN ('committed', 'error')\"\n            query += \" ORDER BY image_name;\"\n            cursor.execute(query, params)\n            rows = cursor.fetchall()\n        return [\n            PlannedImageMove(\n                image_name=row[\"image_name\"],\n                old_subfolder=row[\"old_subfolder\"],","sourceCodeStart":727,"sourceCodeEnd":763,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/image_moves/image_moves_default.py#L727-L763","documentation":"_get_new_subfolder maps a MoveJobStrategy to a destination subfolder layout. If the strategy string is not one of the supported values (e.g. 'category', 'hash', 'date', 'none'/'intermediate' handling), the code raises ValueError('Unknown image subfolder strategy: {strategy}'). It is a configuration-validation error.","triggerScenarios":"Calling count_images_needing_move or _plan_batch (via move_all_images) with a strategy value outside the supported set — typically a typo ('categeory'), a different-cased value ('Category'), or a strategy string from an older/newer API version.","commonSituations":"Config file or API payload using an unsupported/renamed strategy; hand-written scripts passing a strategy name guessed from docs; version upgrade renaming strategy enum values.","solutions":["Use exactly one of the supported strategies as defined by MoveJobStrategy (e.g. 'category', 'hash', 'date').","Check the MoveJobStrategy enum/type in the installed InvokeAI version and match casing/spelling.","If migrating from an older version, map deprecated strategy names to their new equivalents before calling.","Add validation at the config load site so invalid strategies fail fast with a clear message."],"exampleFix":"// before\nservice.count_images_needing_move(strategy=\"folders\")  # ValueError\n// after\nservice.count_images_needing_move(strategy=\"category\")  # supported strategy","handlingStrategy":"validation","validationCode":"SUPPORTED = {'category', 'hash', 'date'}\ndef strategy_is_valid(strategy: str) -> bool:\n    return strategy in SUPPORTED\nassert strategy_is_valid(cfg.strategy), f\"unknown strategy {cfg.strategy!r}\"","typeGuard":"from typing import Literal\nStrategy = Literal['category', 'hash', 'date']\ndef is_strategy(v: str) -> TypeGuard[Strategy]:\n    return v in ('category', 'hash', 'date')","tryCatchPattern":"try:\n    service.count_images_needing_move(strategy=strategy)\nexcept ValueError as e:\n    if \"Unknown image subfolder strategy\" in str(e):\n        strategy = 'category'  # safe default","preventionTips":["Copy strategy names from the MoveJobStrategy definition, not from memory","Validate strategy values at config-load time","Watch for renames when upgrading InvokeAI versions","Keep strategy strings lowercase exactly as defined"],"tags":["configuration","image-move","validation","valueerror"],"backgroundTag":"invalid-configuration-value","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}