{"record":{"id":"bc897abb9ea24505","repo":"calesthio/OpenMontage","slug":"doubao-submit-succeeded-but-did-not-return-data-ta","errorCode":null,"errorMessage":"Doubao submit succeeded but did not return data.task_id","messagePattern":"Doubao submit succeeded but did not return data\\.task_id","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"tools/audio/doubao_tts.py","lineNumber":242,"sourceCode":"        output_path.parent.mkdir(parents=True, exist_ok=True)\n        metadata_path.parent.mkdir(parents=True, exist_ok=True)\n\n        req_id = str(uuid.uuid4())\n        headers = self._headers(\n            api_key=api_key,\n            resource_id=resource_id,\n            request_id=req_id,\n            return_usage=bool(inputs.get(\"return_usage\", True)),\n        )\n        body = self._submit_body(inputs, voice_id=voice_id, request_id=req_id)\n\n        submit_response = requests.post(self.SUBMIT_URL, headers=headers, json=body, timeout=(10, 60))\n        submit_data = self._json_or_raise(submit_response)\n        self._raise_for_doubao_error(submit_response.status_code, submit_data)\n\n        task_id = submit_data.get(\"data\", {}).get(\"task_id\")\n        if not task_id:\n            raise RuntimeError(\"Doubao submit succeeded but did not return data.task_id\")\n\n        query_data = self._poll_query(\n            requests_module=requests,\n            api_key=api_key,\n            resource_id=resource_id,\n            task_id=task_id,\n            return_usage=bool(inputs.get(\"return_usage\", True)),\n            poll_interval=float(inputs.get(\"poll_interval_seconds\", 2.0)),\n            timeout_seconds=int(inputs.get(\"timeout_seconds\", 300)),\n        )\n        data = query_data.get(\"data\", {})\n        audio_url = data.get(\"audio_url\")\n        if not audio_url:\n            raise RuntimeError(\"Doubao task completed but did not return data.audio_url\")\n\n        audio_response = requests.get(audio_url, timeout=(10, 120))\n        audio_response.raise_for_status()\n        output_path.write_bytes(audio_response.content)","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/audio/doubao_tts.py#L224-L260","documentation":"Raised after a successful HTTP POST to the Volcengine Doubao TTS submit endpoint when the parsed JSON body lacks data.task_id. The wrapper treats a submit response without a task id as unusable because every later poll of QUERY_URL keys off task_id. Note the message text is a plain string, not an f-string, so the literal '{query_data...}' braces never interpolate the response body.","triggerScenarios":"POST to SUBMIT_URL returns HTTP 200 with code 20000000 but data is missing or has no task_id key (e.g. data: null, data: {}), or the endpoint shape changed / was routed to a different API that returns a different envelope.","commonSituations":"Volcendpoint/console migration changed the response envelope; the resource_id points at a legacy endpoint; a proxy or gateway stripped fields; the submit actually failed softly but with code 20000000 so _raise_for_doubao_error passed.","solutions":["Log the full submit_data payload when task_id is absent to see the real envelope returned","Verify resource_id matches the current console's speech endpoint and that the X-Api-Key header flow is used","Retry once — transient soft failures occasionally return an empty data object","If the envelope changed upstream, update the key extraction in doubao_tts.py to the new path"],"exampleFix":"// before\ntask_id = submit_data.get(\"data\", {}).get(\"task_id\")\nif not task_id:\n    raise RuntimeError(\"Doubao submit succeeded but did not return data.task_id\")\n\n// after\ntask_id = (submit_data.get(\"data\") or {}).get(\"task_id\")\nif not task_id:\n    raise RuntimeError(\n        f\"Doubao submit succeeded but did not return data.task_id: {submit_data}\"\n    )","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = doubao_tool.execute(inputs)\nexcept RuntimeError as e:\n    if \"data.task_id\" in str(e):\n        logger.error(\"doubao submit envelope missing task_id; dumping last response\")\n        raise\n    raise","preventionTips":["Pin the resource_id/endpoint pair verified against the current Volcengine console","Log every submit response body during integration so envelope drift is caught on first occurrence","Wrap Doubao calls in a single helper so retries and diagnostics live in one place"],"tags":["doubao","tts","api-contract","volcengine"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}