CoplayDev/unity-mcp · error · Exception

Sketchfab {phase} failed (status={res?.Status}): {truncated_

Error message

Sketchfab {phase} failed (status={res?.Status}): {truncated_response}

What it means

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.

Source

Thrown at MCPForUnity/Editor/Services/AssetGen/Providers/SketchfabAdapter.cs:73

            HttpResult res = await http.SendAsync(spec, ct);
            JObject json = ParseOk(res, apiKey, "download");

            string url = json["gltf"]?["url"]?.ToString();
            if (string.IsNullOrEmpty(url))
            {
                throw new Exception(SecretRedactor.Scrub(
                    $"Sketchfab download returned no gltf url for '{uid}': {ProviderHttp.Truncate(res?.Text)}", apiKey));
            }
            return url;
        }

        private static string RawOk(HttpResult res, string apiKey, string phase)
        {
            string text = ProviderHttp.BodyText(res);

            bool ok = res?.Ok == true;
            if (!ok)
                throw new Exception(SecretRedactor.Scrub($"Sketchfab {phase} failed (status={res?.Status}): {ProviderHttp.Truncate(text)}", apiKey));
            return text ?? string.Empty;
        }

        private static JObject ParseOk(HttpResult res, string apiKey, string phase)
        {
            string text = ProviderHttp.BodyText(res);

            JObject json = null;
            if (!string.IsNullOrEmpty(text))
            {
                try { json = JObject.Parse(text); } catch { /* non-JSON */ }
            }

            bool ok = res?.Ok == true;
            if (!ok)
            {
                string detail = json?["detail"]?.ToString() ?? json?["error"]?.ToString() ?? ProviderHttp.Truncate(text);
                throw new Exception(SecretRedactor.Scrub($"Sketchfab {phase} failed (status={res?.Status}): {detail}", apiKey));

View on GitHub (pinned to c21bf496bc)

Solutions

  1. 401/403 -> set a valid Sketchfab API token in settings.
  2. 404 (preview) -> the uid no longer exists; re-search to get a current uid.
  3. 400 (search) -> shorten/escape the query string.
  4. 429/5xx -> retry with backoff.
Defensive patterns

Strategy: retry

Try / catch

try { return await sketchfab.SearchAsync(q, cat, dl, n, cur, key, http, ct); }
catch (Exception ex)
{
    bool transient = ex.Message.Contains("status=429") || ex.Message.Contains("status=5");
    if (transient) await BackoffRetryAsync(() => sketchfab.SearchAsync(q, cat, dl, n, cur, key, http, ct), ct);
}

Prevention

When it happens

Trigger: 401 invalid Sketchfab token; 404 model uid not found (preview); 400 malformed/overlong query (search); 429 rate limit; 5xx Sketchfab outage.

Common situations: Expired or wrong Sketchfab API token; searching with an extremely long query; previewing a deleted/private model; hitting the public API rate ceiling.

Related errors


AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13). Data as JSON: /api/errors/89cf9ffbd46dbb66. Report an issue: GitHub.