CoplayDev/unity-mcp · error · Exception

fal {phase} failed (status={res?.Status}): {detail}

Error message

fal {phase} failed (status={res?.Status}): {detail}

What it means

The audio adapter's ParseOk mirrors the image one: any response with res.Ok == false throws a generic Exception with the phase, HTTP status, and a detail from the JSON 'detail'/'error' field or truncated raw text, all scrubbed of the apiKey.

Source

Thrown at MCPForUnity/Editor/Services/AssetGen/Providers/FalAudioAdapter.cs:180

            }
            catch { return "wav"; }
        }

        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($"fal {phase} failed (status={res?.Status}): {detail}", apiKey));
            }
            return json ?? new JObject();
        }
    }
}

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Read status + detail to classify: 401/403 -> key, 422 -> body/schema (check duration), 429 -> rate limit, 5xx -> retry.
  2. For 5xx and 429, retry with exponential backoff.
  3. Ensure the request body includes all required fields for the chosen audio model (e.g. duration).
  4. Verify the API key is valid with quota.
Defensive patterns

Strategy: retry

Validate before calling

// Pre-validate request inputs (e.g. duration for duration-controllable audio models).
if (string.IsNullOrEmpty(apiKey)) throw new ArgumentException("apiKey required");
if (string.IsNullOrEmpty(modelId)) throw new ArgumentException("modelId required");

Try / catch

for (int attempt = 0; ; attempt++)
{
    try { return await falAudio.ParseOk(res, apiKey, phase); }
    catch (Exception ex) when (IsTransientHttp(ex) && attempt < 4)
    {
        await Task.Delay((int)Math.Pow(2, attempt) * 500, ct);
        continue;
    }
}

Prevention

When it happens

Trigger: Any 4xx/5xx from fal during an audio submit/poll/download: 401/403 (auth), 422 (e.g. missing 'duration' field), 429 (rate limit), 5xx (server error).

Common situations: Invalid/expired API key; missing required fields like duration for a duration-controllable model; rate limiting; wrong audio model id; transient fal outage.

Related errors


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