{"slug": "running-novelai-v5-in-comfyui-nai-diffusion-5-full-works-and-the-error-fetching", "title": "Running NovelAI V5 in ComfyUI: nai-diffusion-5-full works, and the Error fetching Anlas 400 is a moved endpoint", "summary": "A developer verified that NovelAI's nai-diffusion-5-full and nai-diffusion-5-curated model IDs work through the ComfyUI_NAIDGenerator node, despite a README caveat that they had not been confirmed against the live API. The recurring \"Error fetching Anlas\" 400 error was traced not to the models but to the node's _get_user_data function still querying api.novelai.net/user/data, which NovelAI moved to image.novelai.net around the V5 launch; fixing the host in two spots in nodes.py resolves it, though the new endpoint returns trainingStepsLeft as a dictionary that breaks the node's Anlas subtraction. On an Opus account, a 832×1216 image at 28 steps cost 0 Anlas, and the PNG Source metadata read \"NovelAI Diffusion V5 0ADF9AB7\" and \"NovelAI Diffusion V5 DB276663\" respectively.", "body_md": "`nai-diffusion-5-full` and `nai-diffusion-5-curated` work as they are through the ComfyUI_NAIDGenerator node, even though the README says the IDs haven't been checked against the live API. The `Error fetching Anlas` 400 that shows up next to them has nothing to do with the models: the node still asks `https://api.novelai.net/user/data` for your balance, and NovelAI moved its user endpoints to `image.novelai.net`, so two spots in `nodes.py` fix it.\n\n| Version | Description | \n|---|---|\n| 1.0 | 2026-09-13 first written (ComfyUI 0.35.0 + ComfyUI_NAIDGenerator 52da75a, measured on an Opus account) | \n\nThe `Source` metadata in the PNGs the node brought back read `NovelAI Diffusion V5 0ADF9AB7` and `NovelAI Diffusion V5 DB276663` respectively, and on an Opus account one image at Normal size (832×1216) and 28 steps cost 0 Anlas. Two terms if NovelAI is new to you: Anlas is NovelAI's generation credit, and Opus is the top subscription tier, which generates the common sizes without spending any.\n\nI wrote this for people who read the README line \"have not been independently confirmed against the live API yet\" and hesitated, and for anyone hitting `Error fetching Anlas` the way issue #51 describes. I installed ComfyUI v0.35.0 fresh on macOS and pinned the node to its 2026-08-21 commit, `52da75a` (package version 1.0.9).\n\nWire the Anlas Tracker node into Preview Any and run it, and the preview text reads `Error fetching Anlas` while the console prints one line:\n\n```\n[NovelAI] Failed to fetch Anlas balance: 400 Client Error: Bad Request for url: https://api.novelai.net/user/data\n```\n\nThe node added the two V5 model IDs in PR #50 on 2026-08-21, but the README still carries the caveat that they were never compared against the live API. Issue #51, opened the next day, reports a generation 400 on a trial account together with `Error fetching Anlas`, and as of 2026-09-13 it has no replies.\n\nMeanwhile NovelAI moved its user endpoints to `image.novelai.net` around the V5 launch. The 400 from the old host is exactly what I saw in [my earlier Korean post](https://swiftlyaside.tistory.com/7), so I checked whether the node was failing for the same reason.\n\nIt is because `_get_user_data` in `nodes.py` calls `/user/data` with `USER_API_BASE_URL = \"https://api.novelai.net\"`. Attach a token and call both hosts directly, and their answers diverge:\n\n| Call | Response | \n|---|---|\n| `GET https://api.novelai.net/user/data` | 400 `{\"statusCode\":400,\"message\":\"Please refresh NovelAI.net. If using a third-party tool, update to the image URL.\"}` | \n| `GET https://image.novelai.net/user/data` | 200, includes `subscription.trainingStepsLeft` | \n\nWithout a token both hosts return 401, so reproducing this needs a valid one. Swapping the host isn't the end of it either. On the new host `trainingStepsLeft` is not an integer but a shape like `{\"fixedTrainingStepsLeft\": 9898, \"purchasedTrainingSteps\": 32}`, so the Tracker text prints the dictionary verbatim and the Generate node's before-and-after subtraction `start_anlas - final_anlas` dies with `TypeError: unsupported operand type(s) for -: 'dict' and 'dict'`.\n\nThe model IDs themselves were fine. Here is what a ModelOption → Generate → Save Image workflow returned over `POST /prompt`, with the same prompt, seed, and 28 steps as the earlier post:\n\n| Model | Size | Result | PNG `Source` | Subscription Anlas | \n|---|---|---|---|---|\n| `nai-diffusion-5-full` | 832×1216 | 200, 4.1 s | `NovelAI Diffusion V5 0ADF9AB7` | 9,898 → 9,898 | \n| `nai-diffusion-5-curated` | 512×768 | 200, 1.6 s | `NovelAI Diffusion V5 DB276663` | 9,898 → 9,898 | \n\nThere is one trap. The PNG that Save Image writes keeps only the `prompt` chunk, and the `Source` field NovelAI set is gone. The node saves the original separately under a running number such as `output/NAI_autosave_00001_.png`, so read the metadata from the file whose number matches the run you just made.\n\n`_get_user_data` in `nodes.py` in two places. Point the host at `image.novelai.net`, and normalize the dictionary-shaped `trainingStepsLeft` into an integer total:\n\n```\n-    USER_API_BASE_URL = \"https://api.novelai.net\"\n+    USER_API_BASE_URL = \"https://image.novelai.net\"\n@@\n     response.raise_for_status()\n-    return response.json()\n+    data = response.json()\n+    steps = data.get(\"subscription\", {}).get(\"trainingStepsLeft\")\n+    if isinstance(steps, dict):\n+        data[\"subscription\"][\"trainingStepsLeft\"] = int(steps.get(\"fixedTrainingStepsLeft\", 0) or 0) + int(steps.get(\"purchasedTrainingSteps\", 0) or 0)\n+    return data\n```\n\n`9930 Anlas`. That is the subscription 9,898 plus the purchased 32, the same number the web UI shows as your total, and when I generated one more V5 image at Normal size after the patch, the console printed `Generation cost: 0 Anlas`.` nai-diffusion-5-full` in ModelOption is all there is to it. On Opus, leave `limit_opus_free` on and Normal size at 28 steps or fewer stays in the free band.\nImage: the sample output was generated with NovelAI Diffusion V5.\n\nBoth V5 model IDs work through the node as shipped, and the `Error fetching Anlas` 400 is the balance lookup still pointing at `api.novelai.net`. Fixing it takes the new host plus one normalization, because `trainingStepsLeft` now arrives as a dictionary rather than an integer.", "url": "https://wpnews.pro/news/running-novelai-v5-in-comfyui-nai-diffusion-5-full-works-and-the-error-fetching", "canonical_source": "https://dev.to/ilan_kim/running-novelai-v5-in-comfyui-nai-diffusion-5-full-works-and-the-error-fetching-anlas-400-is-a-18gl", "published_at": "2026-09-13 07:59:16+00:00", "updated_at": "2026-09-13 08:26:43.501451+00:00", "lang": "en", "topics": ["generative-ai", "ai-tools", "developer-tools", "ai-products"], "entities": ["NovelAI", "ComfyUI", "ComfyUI_NAIDGenerator", "nai-diffusion-5-full", "nai-diffusion-5-curated", "nodes.py"], "alternates": {"html": "https://wpnews.pro/news/running-novelai-v5-in-comfyui-nai-diffusion-5-full-works-and-the-error-fetching", "markdown": "https://wpnews.pro/news/running-novelai-v5-in-comfyui-nai-diffusion-5-full-works-and-the-error-fetching.md", "text": "https://wpnews.pro/news/running-novelai-v5-in-comfyui-nai-diffusion-5-full-works-and-the-error-fetching.txt", "jsonld": "https://wpnews.pro/news/running-novelai-v5-in-comfyui-nai-diffusion-5-full-works-and-the-error-fetching.jsonld"}}