{"record":{"id":"e3ad611bce2b406d","repo":"invoke-ai/InvokeAI","slug":"call-saved-workflow-exceeds-remaining-queue-capaci-e3ad61","errorCode":null,"errorMessage":"call_saved_workflow exceeds remaining queue capacity for child workflow executions","messagePattern":"call_saved_workflow exceeds remaining queue capacity for child workflow executions","errorType":"validation","errorClass":"TooManySessionsError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/session_queue/session_queue_sqlite.py","lineNumber":1208,"sourceCode":"        if workflow_call_execution is None:\n            raise ValueError(\"Parent queue item is missing active workflow call execution metadata.\")\n\n        session_json = child_session.model_dump_json(warnings=False, exclude_none=True)\n        field_values_json = json.dumps(field_values, default=to_jsonable_python) if field_values is not None else None\n        root_item_id = parent_queue_item.root_item_id or parent_queue_item.item_id\n\n        with self._db.transaction() as cursor:\n            cursor.execute(\n                \"\"\"--sql\n                SELECT COUNT(*)\n                FROM session_queue\n                WHERE queue_id = ? AND status = 'pending'\n                \"\"\",\n                (parent_queue_item.queue_id,),\n            )\n            pending_count = cast(int, cursor.fetchone()[0])\n            if pending_count >= self.__invoker.services.configuration.max_queue_size:\n                raise TooManySessionsError(\n                    \"call_saved_workflow exceeds remaining queue capacity for child workflow executions\"\n                )\n\n            cursor.execute(\n                \"\"\"--sql\n                INSERT INTO session_queue (\n                    queue_id,\n                    session,\n                    session_id,\n                    batch_id,\n                    field_values,\n                    priority,\n                    workflow,\n                    origin,\n                    destination,\n                    retried_from_item_id,\n                    user_id,\n                    workflow_call_id,","sourceCodeStart":1190,"sourceCodeEnd":1226,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/session_queue/session_queue_sqlite.py#L1190-L1226","documentation":"TooManySessionsError raised by enqueue_workflow_call_child when the number of already-pending child queue items for the parent's queue_id has reached max_queue_size (the 'pending' count >= configured limit). It protects the queue from unbounded growth when a workflow spawns child executions.","triggerScenarios":"Calling enqueue_workflow_call_child while COUNT(*) of pending items for the queue >= services.configuration.max_queue_size; enqueueing many child workflow calls in a loop without draining; a stuck/never-executing pending item keeping the count at the cap.","commonSituations":"max_queue_size set low (or left at a small default) while running fan-out workflows; batch scripts enqueuing dozens of child workflows; environments where workers are stopped so pending items accumulate; version changes that made child workflows count against the same pending budget.","solutions":["Raise max_queue_size in the InvokeAI configuration (or via the config service) before enqueueing.","Drain pending items first: wait for workers to move items to 'completed'/'canceled' or explicitly cancel pending items.","Refactor the workflow to enqueue child calls incrementally (enqueue the next only after the previous completes) instead of all at once.","Check for stuck pending items (dead worker) and requeue/cancel them to free capacity."],"exampleFix":"// before\nchild = queue.enqueue_workflow_call_child(...)  # raises when pending >= max_queue_size\n// after\nif queue.get_pending_queue_count(parent_queue_item.queue_id) < config.max_queue_size:\n    child = queue.enqueue_workflow_call_child(...)\nelse:\n    raise DeferredEnqueue(...)  # retry after workers drain the queue","handlingStrategy":"try-catch","validationCode":"pending = queue.get_queue_status(queue_id)  # or COUNT of pending items\nif pending >= config.max_queue_size:\n    raise RuntimeError('queue full: drain pending items before enqueueing child workflow')","typeGuard":"def has_child_capacity(queue, queue_id: str, config) -> bool:\n    pending = queue.get_queue_status(queue_id).pending  # adapt to actual accessor\n    return pending < config.max_queue_size","tryCatchPattern":"try:\n    child = queue.enqueue_workflow_call_child(...)\nexcept TooManySessionsError:\n    wait_until_workers_drain(queue_id)\n    child = queue.enqueue_workflow_call_child(...)  # bounded retry","preventionTips":["Size max_queue_size above your worst-case child-workflow fan-out.","Enqueue children incrementally as predecessors complete.","Monitor pending count and alert before hitting the cap.","Avoid keeping workers stopped while spawning child workflows."],"tags":["queue","capacity","limit-exceeded"],"backgroundTag":"queue-capacity-exceeded","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}