{"record":{"id":"f8ec1bb3b8a84ee4","repo":"binary-husky/gpt_academic","slug":"request-to-the-target-service-failed-str-e","errorCode":null,"errorMessage":"Request to the target service failed: {str(e)}","messagePattern":"Request to the target service failed: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"shared_utils/fastapi_server.py","lineNumber":237,"sourceCode":"                        temp_file = os.path.join(temp_folder, f'{temp_file_name}.mp3')\n                        await tts.save(temp_file)\n                        try:\n                            mp3_audio = AudioSegment.from_file(temp_file, format=\"mp3\")\n                            mp3_audio.export(temp_file, format=\"wav\")\n                            with open(temp_file, 'rb') as wav_file: t = wav_file.read()\n                            os.remove(temp_file)\n                            return Response(content=t)\n                        except:\n                            raise RuntimeError(\"ffmpeg未安装，无法处理EdgeTTS音频。安装方法见`https://github.com/jiaaro/pydub#getting-ffmpeg-set-up`\")\n                    if TTS_TYPE == \"LOCAL_SOVITS_API\":\n                        # Forward the request to the target service\n                        TARGET_URL = get_conf(\"GPT_SOVITS_URL\")\n                        body = await request.body()\n                        resp = await client.post(TARGET_URL, content=body, timeout=60)\n                        # Return the response from the target service\n                        return Response(content=resp.content, status_code=resp.status_code, headers=dict(resp.headers))\n                except httpx.RequestError as e:\n                    raise HTTPException(status_code=400, detail=f\"Request to the target service failed: {str(e)}\")\n        @gradio_app.post(\"/vits\")\n        async def forward_post_request(request: Request):\n            return await forward_request(request, \"POST\")\n\n    # --- --- app_lifespan --- ---\n    from contextlib import asynccontextmanager\n    @asynccontextmanager\n    async def app_lifespan(app):\n        async def startup_gradio_app():\n            if gradio_app.get_blocks().enable_queue:\n                gradio_app.get_blocks().startup_events()\n        async def shutdown_gradio_app():\n            pass\n        await startup_gradio_app() # startup logic here\n        yield  # The application will serve requests after this point\n        await shutdown_gradio_app() # cleanup/shutdown logic here\n\n    # --- --- FastAPI --- ---","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/shared_utils/fastapi_server.py#L219-L255","documentation":"In the TTS forwarding path for TTS_TYPE == 'LOCAL_SOVITS_API', the request body is proxied with httpx to GPT_SOVITS_URL (timeout=60). Any httpx.RequestError — connection refused, DNS failure, timeout, TLS error — is caught and returned as HTTPException(400, 'Request to the target service failed: {e}'). It signals the local GPT-SoVITS inference service is unreachable, not a problem with gpt_academic itself.","triggerScenarios":"TTS request while the GPT-SoVITS service is down, wrong GPT_SOVITS_URL in config, service listening on a different host/port than configured, or inference exceeding the 60 s httpx timeout.","commonSituations":"GPT-SoVITS not started or still loading models when the first TTS call arrives; docker networking misconfiguration (localhost vs container name); firewall blocking the port; long synthesis exceeding timeout=60.","solutions":["Start the GPT-SoVITS service and confirm it responds (curl its health/TTS endpoint directly).","Fix GPT_SOVITS_URL in config.py to the correct host:port reachable from this process.","If long audio routinely exceeds 60 s, raise the timeout in the client.post call or split the text.","In docker-compose, use service names instead of 127.0.0.1."],"exampleFix":"# before\nresp = await client.post(TARGET_URL, content=body, timeout=60)\n\n# after\nresp = await client.post(TARGET_URL, content=body, timeout=120)  # long syntheses","handlingStrategy":"retry","validationCode":"import httpx, socket\nfrom toolbox import get_conf\nTARGET_URL = get_conf('GPT_SOVITS_URL')\nhost = httpx.URL(TARGET_URL).host\nport = httpx.URL(TARGET_URL).port or 80\nwith socket.socket() as s:\n    s.settimeout(2)\n    sovit_up = s.connect_ex((host, port)) == 0\nif not sovit_up:\n    return JSONResponse({'error': 'GPT-SoVITS service not reachable'}, 503)","typeGuard":null,"tryCatchPattern":"for attempt in range(2):\n    try:\n        resp = await client.post(TARGET_URL, content=body, timeout=60)\n        break\n    except httpx.RequestError:\n        if attempt == 1:\n            raise HTTPException(503, 'TTS backend unavailable')\n        await asyncio.sleep(1)","preventionTips":["Health-check the GPT-SoVITS endpoint at startup.","Use correct host/port (container names in docker-compose, not localhost).","Size the httpx timeout to the longest expected synthesis."],"tags":["tts","gpt-sovits","proxy","httpx","network"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}