{"record":{"id":"89cf9ffbd46dbb66","repo":"CoplayDev/unity-mcp","slug":"sketchfab-phase-failed-status-res-status","errorCode":null,"errorMessage":"Sketchfab {phase} failed (status={res?.Status}): {truncated_response}","messagePattern":"Sketchfab (.+?) failed \\(status=(.+?)\\): (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"MCPForUnity/Editor/Services/AssetGen/Providers/SketchfabAdapter.cs","lineNumber":73,"sourceCode":"            HttpResult res = await http.SendAsync(spec, ct);\n            JObject json = ParseOk(res, apiKey, \"download\");\n\n            string url = json[\"gltf\"]?[\"url\"]?.ToString();\n            if (string.IsNullOrEmpty(url))\n            {\n                throw new Exception(SecretRedactor.Scrub(\n                    $\"Sketchfab download returned no gltf url for '{uid}': {ProviderHttp.Truncate(res?.Text)}\", apiKey));\n            }\n            return url;\n        }\n\n        private static string RawOk(HttpResult res, string apiKey, string phase)\n        {\n            string text = ProviderHttp.BodyText(res);\n\n            bool ok = res?.Ok == true;\n            if (!ok)\n                throw new Exception(SecretRedactor.Scrub($\"Sketchfab {phase} failed (status={res?.Status}): {ProviderHttp.Truncate(text)}\", apiKey));\n            return text ?? string.Empty;\n        }\n\n        private static JObject ParseOk(HttpResult res, string apiKey, string phase)\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?[\"detail\"]?.ToString() ?? json?[\"error\"]?.ToString() ?? ProviderHttp.Truncate(text);\n                throw new Exception(SecretRedactor.Scrub($\"Sketchfab {phase} failed (status={res?.Status}): {detail}\", apiKey));","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/CoplayDev/unity-mcp/blob/c21bf496bca87d54e75bad048563c3adb1782081/MCPForUnity/Editor/Services/AssetGen/Providers/SketchfabAdapter.cs#L55-L91","documentation":"Thrown by SketchfabAdapter.RawOk (used by SearchAsync and PreviewAsync, which return raw JSON strings) when res.Ok is false. The phase label ('search' or 'preview') and the HTTP status plus truncated body are included, scrubbed of the key. This is the failure path for the read-only Sketchfab GETs.","triggerScenarios":"401 invalid Sketchfab token; 404 model uid not found (preview); 400 malformed/overlong query (search); 429 rate limit; 5xx Sketchfab outage.","commonSituations":"Expired or wrong Sketchfab API token; searching with an extremely long query; previewing a deleted/private model; hitting the public API rate ceiling.","solutions":["401/403 -> set a valid Sketchfab API token in settings.","404 (preview) -> the uid no longer exists; re-search to get a current uid.","400 (search) -> shorten/escape the query string.","429/5xx -> retry with backoff."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return await sketchfab.SearchAsync(q, cat, dl, n, cur, 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(() => sketchfab.SearchAsync(q, cat, dl, n, cur, key, http, ct), ct);\n}","preventionTips":["Keep the Sketchfab token valid; surface 401 clearly.","Escape/shorten search queries to avoid 400s.","For preview, confirm a uid exists before requesting it."],"tags":["sketchfab","http-error","asset-gen","marketplace","network"],"backgroundTag":null,"analyzedSha":"c21bf496bca87d54e75bad048563c3adb1782081","analyzedAt":"2026-08-13T17:36:56.095Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}