{"record":{"id":"bf04281b53a62393","repo":"CoplayDev/unity-mcp","slug":"openrouter-request-failed-status-res-status","errorCode":null,"errorMessage":"OpenRouter request failed (status={res?.Status}): {detail}","messagePattern":"OpenRouter request failed \\(status=(.+?)\\): (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"MCPForUnity/Editor/Services/AssetGen/Providers/OpenRouterAdapter.cs","lineNumber":151,"sourceCode":"            return null;\n        }\n\n        private static JObject ParseOk(HttpResult res, string apiKey)\n        {\n            string text = ProviderHttp.BodyText(res);\n\n            JObject json = null;\n            if (!string.IsNullOrEmpty(text))\n            {\n                try { json = JObject.Parse(text); } catch { /* non-JSON */ }\n            }\n\n            bool ok = res?.Ok == true;\n            if (!ok)\n            {\n                string detail = json?[\"error\"]?[\"message\"]?.ToString() ?? json?[\"error\"]?.ToString()\n                                ?? ProviderHttp.Truncate(text);\n                throw new Exception(SecretRedactor.Scrub($\"OpenRouter request failed (status={res?.Status}): {detail}\", apiKey));\n            }\n            return json ?? new JObject();\n        }\n    }\n}\n","sourceCodeStart":133,"sourceCodeEnd":157,"githubUrl":"https://github.com/CoplayDev/unity-mcp/blob/c21bf496bca87d54e75bad048563c3adb1782081/MCPForUnity/Editor/Services/AssetGen/Providers/OpenRouterAdapter.cs#L133-L157","documentation":"Thrown by OpenRouterAdapter.ParseOk when the OpenRouter chat-completions request returns a non-ok HTTP status. The detail is read from json.error.message, then json.error, then truncated raw text, and scrubbed of the API key. OpenRouter is used for image generation via a multimodal model that returns an inline base64 image.","triggerScenarios":"401 invalid OpenRouter key; 400 the selected model does not support image output or the 'modalities' field; 402 insufficient credits; 429 rate limit; model name typo (e.g. a discontinued model); content-policy rejection.","commonSituations":"Default model google/gemini-2.5-flash-image rotated or renamed by OpenRouter; user set a text-only model for image generation; credits exhausted; a prompt flagged by safety filters.","solutions":["Read error.message from the exception text to get OpenRouter's reason.","401 -> set a valid OpenRouter API key in settings; 402 -> add credits; 429 -> back off.","400 with a modality/model complaint -> confirm the model supports image output (default google/gemini-2.5-flash-image) and leave model unset to use the default.","Retry on 429/5xx with exponential backoff."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await openrouter.SubmitAsync(req, key, http, ct); }\ncatch (Exception ex)\n{\n    bool transient = ex.Message.Contains(\"status=429\") || ex.Message.Contains(\"status=5\");\n    if (transient) await BackoffRetryAsync(() => openrouter.SubmitAsync(req, key, http, ct), ct);\n}","preventionTips":["Confirm the model supports image output (default google/gemini-2.5-flash-image); leave model unset to use it.","Keep OpenRouter credits funded and the key valid.","Surface error.message to distinguish auth vs. model-capability vs. rate-limit."],"tags":["openrouter","http-error","image-generation","asset-gen","network"],"backgroundTag":null,"analyzedSha":"c21bf496bca87d54e75bad048563c3adb1782081","analyzedAt":"2026-08-13T17:36:56.095Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}