{"record":{"id":"dc6d89325ff0af5e","repo":"3b1b/manim","slug":"invalid-scene-number","errorCode":null,"errorMessage":"Invalid scene number","messagePattern":"Invalid scene number","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"manimlib/extract_scene.py","lineNumber":54,"sourceCode":"        return False\n    return True\n\n\ndef prompt_user_for_choice(scene_classes):\n    name_to_class = {}\n    max_digits = len(str(len(scene_classes)))\n    for idx, scene_class in enumerate(scene_classes, start=1):\n        name = scene_class.__name__\n        print(f\"{str(idx).zfill(max_digits)}: {name}\")\n        name_to_class[name] = scene_class\n    try:\n        user_input = input(\"\\nSelect which scene to render (by name or number): \")\n        return [\n            name_to_class[split_str] if not split_str.isnumeric() else scene_classes[int(split_str) - 1]\n            for split_str in user_input.replace(\" \", \"\").split(\",\")\n        ]\n    except IndexError:\n        log.error(\"Invalid scene number\")\n        sys.exit(2)\n    except KeyError:\n        log.error(\"Invalid scene name\")\n        sys.exit(2)\n    except EOFError:\n        sys.exit(1)\n\n\ndef compute_total_frames(scene_class, scene_config):\n    \"\"\"\n    When a scene is being written to file, a copy of the scene is run with\n    skip_animations set to true so as to count how many frames it will require.\n    This allows for a total progress bar on rendering, and also allows runtime\n    errors to be exposed preemptively for long running scenes.\n    \"\"\"\n    pre_config = copy.deepcopy(scene_config)\n    pre_config[\"file_writer_config\"][\"write_to_movie\"] = False\n    pre_config[\"file_writer_config\"][\"save_last_frame\"] = False","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/3b1b/manim/blob/dee01804d47b9f94402d71472674710dcac125b8/manimlib/extract_scene.py#L36-L72","documentation":"When multiple scenes exist and none is named on the command line, manim prints a numbered menu and reads a comma-separated selection. A token that is numeric indexes scene_classes[int(s) - 1]; an out-of-range number raises IndexError, which is caught, logged as 'Invalid scene number', and exits with status 2.","triggerScenarios":"Entering '5' or '0' when only 3 scenes are listed; entering '2,7' where 7 exceeds the count; leading zeros are fine but a number past the end is not.","commonSituations":"Miscounting the printed menu; piping a stale selection into stdin from a script that assumed an older scene list; typing the line number of the file instead of the menu number.","solutions":["Pick a number between 1 and the count shown in the menu","Bypass the menu entirely by naming the scene: manim file.py MyScene","In scripts, pass scene names via CLI args instead of relying on interactive stdin"],"exampleFix":"# before\n$ manim file.py   # menu shows 1: A, 2: B\n> 3\n# after\n$ manim file.py B","handlingStrategy":"validation","validationCode":"choice = input(\"Scene number: \")\nn = int(choice)\nassert 1 <= n <= len(scene_classes), f\"pick 1..{len(scene_classes)}\"","typeGuard":"def is_valid_scene_number(s: str, count: int) -> bool:\n    return s.isnumeric() and 1 <= int(s) <= count","tryCatchPattern":null,"preventionTips":["Pass scene names on the command line instead of relying on the interactive menu in scripts","Count the printed menu entries before typing a number"],"tags":["cli","scene-selection","interactive","startup"],"backgroundTag":null,"analyzedSha":"dee01804d47b9f94402d71472674710dcac125b8","analyzedAt":"2026-08-14T19:53:44.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}