{"record":{"id":"f441391269be5bb2","repo":"Sonarr/Sonarr","slug":"indexer-api-call-returned-an-error-0","errorCode":null,"errorMessage":"Indexer API call returned an error [{0}]","messagePattern":"Indexer API call returned an error \\[(.+?)\\]","errorType":"exception","errorClass":"IndexerException","httpStatus":null,"severity":"error","filePath":"src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetParser.cs","lineNumber":57,"sourceCode":"            {\n                throw new IndexerException(indexerResponse, \"Indexer responded with html content. Site is likely blocked or unavailable.\");\n            }\n\n            if (indexerResponse.Content.ContainsIgnoreCase(\"Call Limit Exceeded\"))\n            {\n                throw new RequestLimitReachedException(\"Cannot do more than 150 API requests per hour.\");\n            }\n\n            if (indexerResponse.Content == \"Query execution was interrupted\")\n            {\n                throw new IndexerException(indexerResponse, \"Indexer API returned an internal server error\");\n            }\n\n            var jsonResponse = new HttpResponse<JsonRpcResponse<BroadcastheNetTorrents>>(indexerHttpResponse).Resource;\n\n            if (jsonResponse.Error != null || jsonResponse.Result == null)\n            {\n                throw new IndexerException(indexerResponse, \"Indexer API call returned an error [{0}]\", jsonResponse.Error);\n            }\n\n            if (jsonResponse.Result.Results == 0 || jsonResponse.Result.Torrents?.Values == null)\n            {\n                return results;\n            }\n\n            var protocol = indexerResponse.HttpRequest.Url.Scheme + \":\";\n\n            foreach (var torrent in jsonResponse.Result.Torrents.Values)\n            {\n                var torrentInfo = new TorrentInfo\n                {\n                    Guid = $\"BTN-{torrent.TorrentID}\",\n                    InfoUrl = $\"{protocol}//broadcasthe.net/torrents.php?id={torrent.GroupID}&torrentid={torrent.TorrentID}\",\n                    DownloadUrl = RegexProtocol.Replace(torrent.DownloadURL, protocol),\n                    Title = CleanReleaseName(torrent.ReleaseName),\n                    InfoHash = torrent.InfoHash,","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/Sonarr/Sonarr/blob/da2284d7eaab22ed9b2ca698af690148d691e967/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetParser.cs#L39-L75","documentation":"Thrown by the BroadcastheNet parser when the deserialized JSON-RPC response envelope contains a non-null Error property or a null Result property. Per JSON-RPC 2.0 spec, a non-null error field means the server rejected the request (authentication failure, invalid parameters, malformed method call). Null result without error indicates a protocol-level violation from the BTN API.","triggerScenarios":"The BTN API returns a valid JSON-RPC response with an error object — e.g. invalid API key, insufficient privileges, unknown method, parameter validation failure, or an internal BTN-side processing error that JSON-RPC reports gracefully. Also triggered if the response deserializes successfully but the Result member is unexpectedly null.","commonSituations":"API key revoked or expired on the BTN side; the BTN API changed its method signatures in a version update; calling a BTN method the account lacks permission for; malformed search parameters that BTN rejects; BTN API behind a proxy that strips the result payload.","solutions":["Inspect the interpolated error message in the exception — jsonResponse.Error contains BTN's explanation (e.g. 'Invalid API Key', 'Bad parameters').","If the error mentions authentication, verify and re-enter the BTN API key in the indexer settings.","If parameters are rejected, check that the search criteria (tvdbid, season, episode) are valid numbers and not empty.","If the error is intermittent, it may be BTN-side throttling returning an error object rather than the text-based throttle — reduce request frequency.","Check BTN API changelog or community forums if the error appeared after a BTN update."],"exampleFix":"// The error details are in jsonResponse.Error — log them for diagnosis\nif (jsonResponse.Error != null || jsonResponse.Result == null)\n{\n    // before: error detail is interpolated but easily lost\n    throw new IndexerException(indexerResponse,\n        \"Indexer API call returned an error [{0}]\", jsonResponse.Error);\n\n    // after: distinguish auth errors from generic errors so the caller\n    // can apply the right backoff strategy\n    // if (jsonResponse.Error.Code == 401 || jsonResponse.Error.Message.ContainsIgnoreCase(\"api key\"))\n    //     throw new ApiKeyException(jsonResponse.Error.Message);\n    // throw new IndexerException(indexerResponse,\n    //     \"BTN API error [{0}]: {1}\", jsonResponse.Error.Code, jsonResponse.Error.Message);\n}","handlingStrategy":"try-catch","validationCode":"// Validate BTN API key is configured before making requests\nif (settings.ApiKey.IsNullOrWhiteSpace())\n{\n    throw new ApiKeyException(\"BTN API key is not configured\");\n}","typeGuard":null,"tryCatchPattern":"// IndexerException carries the BTN JSON-RPC error detail in its message.\n// Catch it and inspect the message for auth errors vs. transient errors:\ntry\n{\n    return await FetchPage(request, parser);\n}\ncatch (IndexerException ex)\n{\n    if (ex.Message.ContainsIgnoreCase(\"api key\") || ex.Message.ContainsIgnoreCase(\"unauthorized\"))\n    {\n        // Auth failure — surface to user for credential fix\n        throw new ApiKeyException(ex.Message);\n    }\n    // Transient or parameter error — log and continue\n    _logger.Warn(ex, \"BTN API error, will retry on next cycle\");\n    return Array.Empty<ReleaseInfo>();\n}","preventionTips":["Verify the BTN API key in indexer settings matches the key in your BTN account profile.","Keep search parameters well-formed — BTN expects numeric tvdbid, valid season/episode numbers.","Monitor for BTN API version changes via BTN community channels.","Test the indexer connection after updating API credentials."],"tags":["indexer","broadcasthe-net","json-rpc","api-error","authentication"],"backgroundTag":null,"analyzedSha":"da2284d7eaab22ed9b2ca698af690148d691e967","analyzedAt":"2026-08-13T15:53:02.562Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}