{"record":{"id":"bdce83809dd711ec","repo":"invoke-ai/InvokeAI","slug":"call-saved-workflow-could-not-access-board-board","errorCode":null,"errorMessage":"call_saved_workflow could not access board '{board_id}' for image generator expansion","messagePattern":"call_saved_workflow could not access board '(.+?)' for image generator expansion","errorType":"exception","errorClass":"UnsupportedWorkflowNodeError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/session_processor/workflow_call_batch.py","lineNumber":328,"sourceCode":"\ndef _assert_user_can_access_board(board_id: str, services: Any, user_id: str | None) -> None:\n    if not user_id:\n        return\n\n    board_records = getattr(services, \"board_records\", None)\n    if board_records is None or not hasattr(board_records, \"get\"):\n        return\n\n    users = getattr(services, \"users\", None)\n    user = users.get(user_id) if users is not None and hasattr(users, \"get\") else None\n    is_admin = bool(user and getattr(user, \"is_admin\", False))\n    if is_admin:\n        return\n\n    try:\n        board_record = board_records.get(board_id)\n    except Exception as e:\n        raise UnsupportedWorkflowNodeError(\n            f\"call_saved_workflow could not access board '{board_id}' for image generator expansion\"\n        ) from e\n\n    if getattr(board_record, \"user_id\", None) == user_id:\n        return\n\n    board_visibility = getattr(board_record, \"board_visibility\", BoardVisibility.Private)\n    if isinstance(board_visibility, str):\n        try:\n            board_visibility = BoardVisibility(board_visibility)\n        except ValueError:\n            board_visibility = BoardVisibility.Private\n    if board_visibility in {BoardVisibility.Shared, BoardVisibility.Public}:\n        return\n\n    if hasattr(board_records, \"get_all\"):\n        try:\n            accessible_boards = board_records.get_all(","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/session_processor/workflow_call_batch.py#L310-L346","documentation":"While expanding an image_generator (images_from_board) node in a called batch child workflow, InvokeAI tried to fetch the referenced board and the board_records.get(board_id) call raised. The underlying storage exception is chained ('from e'); the board may not exist, may be corrupted, or the store may be failing, and expansion cannot enumerate the board's images.","triggerScenarios":"Calling a saved workflow whose image_generator node references a board_id that does not exist in the board records store (deleted board, board from another install/database, or a transient DB failure), when the caller has a user_id and the service layer propagates the error.","commonSituations":"Sharing workflows between machines/databases where board ids don't resolve; deleting a board that a saved workflow still references; SQLite/database corruption or read failures; running with multi-user auth where boards live in another account's records.","solutions":["Verify the board_id exists (e.g. list boards via the API) and update the workflow's image_generator node to a valid board id","Remove the board reference and supply images via a direct list on an image_batch node instead","Restore the missing board or repair the board records database if the store is failing","Call without a user_id context only if board access control is not required, or run as an admin user"],"exampleFix":"// before\n{ \"type\": \"image_generator_images_from_board\", \"board_id\": \"b0ard-from-old-install\" }\n// after\n{ \"type\": \"image_generator_images_from_board\", \"board_id\": \"1a2b3c4d-...\" }  // existing board id","handlingStrategy":"try-catch","validationCode":"def board_exists(services, board_id: str) -> bool:\n    try:\n        services.board_records.get(board_id)\n        return True\n    except Exception:\n        return False\n\n# before building child sessions\nbad = [v for node in workflow.get(\"nodes\", []) if isinstance(node, dict)\n       for v in [node.get(\"data\", {}).get(\"inputs\", {}).get(\"generator\", {}).get(\"value\", {})]\n       if isinstance(v, dict) and v.get(\"type\") == \"image_generator_images_from_board\"\n       and v.get(\"board_id\") and not board_exists(services, v[\"board_id\"])]","typeGuard":"def board_record_ok(record: object) -> bool:\n    return record is not None and getattr(record, \"board_id\", None) is not None","tryCatchPattern":"try:\n    sessions = build_batch_child_workflow_sessions(...)\nexcept UnsupportedWorkflowNodeError as e:\n    m = re.search(r\"could not access board '(.+?)'\", str(e))\n    if m:\n        board_id = m.group(1)\n        # check board exists via API before retrying\n        if not board_exists(services, board_id):\n            raise BoardGoneError(board_id) from e\n    raise","preventionTips":["Verify board ids exist (boards list API) before referencing them in saved workflows","Update workflows when boards are deleted","Avoid sharing workflow JSON across installs with different databases","Check database health if board lookups start failing unexpectedly"],"tags":["board","workflow","permissions","storage","invokeai"],"backgroundTag":"board-not-found","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}