{"record":{"id":"044a5182aea95e01","repo":"Comfy-Org/ComfyUI","slug":"the-prompt-references-audio-idx-but-only-voices","errorCode":null,"errorMessage":"The prompt references @Audio{idx}, but only voices 1..{len(voices)} exist.","messagePattern":"The prompt references @Audio(.+?), but only voices 1\\.\\.(.+?) exist\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_api_nodes/nodes_grok.py","lineNumber":119,"sourceCode":"    audio_indices: dict[int, int] = {}\n    for slot, voice in enumerate(voices, start=1):\n        if voice != \"none\":\n            audio_indices[slot] = len(audio_indices)\n\n    def repl(match: re.Match) -> str:\n        kind = match.group(1).lower()\n        idx = int(match.group(\"idx\") or 1)\n        if kind == \"image\":\n            if not 1 <= idx <= total_images:\n                raise ValueError(\n                    f\"The prompt references @Image{idx}, but only {total_images} \"\n                    f\"reference images are connected (a batched input counts once per image).\"\n                )\n            return f\"<IMAGE_{idx - 1}>\"\n        if idx not in audio_indices:\n            if 1 <= idx <= len(voices):\n                raise ValueError(f\"The prompt references @Audio{idx}, but 'voice_{idx}' is set to 'none'.\")\n            raise ValueError(f\"The prompt references @Audio{idx}, but only voices 1..{len(voices)} exist.\")\n        return f\"<AUDIO_{audio_indices[idx]}>\"\n\n    prev = None\n    while prev != prompt:\n        prev = prompt\n        prompt = _GROK_REF_TAG_RE.sub(repl, prompt)\n    return prompt\n\n\ndef _extract_grok_price(response) -> float | None:\n    if response.usage and response.usage.cost_in_usd_ticks is not None:\n        return response.usage.cost_in_usd_ticks / 10_000_000_000\n    return None\n\n\ndef _extract_grok_video_price(response) -> float | None:\n    price = _extract_grok_price(response)\n    if price is not None:","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_api_nodes/nodes_grok.py#L101-L137","documentation":"Grok @AudioN tag resolution failure where the index is entirely out of range: idx exceeds the number of voice slots (len(voices)), so no voice_{idx} exists at all. Distinct from the 'none' case — here the slot itself is missing. Raised inside the regex substitution loop, before any API call is made.","triggerScenarios":"Prompt contains e.g. '@Audio4' while only 3 voice inputs exist (voices list length 3), or '@Audio' with zero voices configured (idx defaults to 1, and 1 <= idx <= 0 is impossible).","commonSituations":"Prompt templates written for more voice slots than the node version exposes; deleting voice inputs after writing the prompt; typo like '@Audio7' instead of '@Audio1'; assuming default-voice tagging works with no voices connected.","solutions":["Change the tag to a valid slot: @Audio1..@Audio{len(voices)}.","Add the missing voice input(s) to the node so the index exists.","Remove the tag if that voice is no longer used."],"exampleFix":"# before: 3 voice slots\nprompt = \"@Audio4 sings the chorus\"  # raises\n\n# after\nprompt = \"@Audio3 sings the chorus\"","handlingStrategy":"validation","validationCode":"refs = {int(m.group(\"idx\") or 1) for m in _TAG.finditer(prompt) if m.group(1).lower() == \"audio\"}\nout_of_range = [i for i in refs if i > len(voices)]\nassert not out_of_range, f\"tags exceed {len(voices)} voice slots: {out_of_range}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check every @AudioN tag against the current number of voice slots.","Re-audit prompts after deleting voice inputs.","Note bare '@Audio' defaults to index 1 and fails when no voices exist."],"tags":["grok","xai","prompt-template","audio","input-validation","comfy-api-nodes"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}