{"record":{"id":"8262dd2df4c33c22","repo":"calesthio/OpenMontage","slug":"exc","errorCode":null,"errorMessage":"{exc}","messagePattern":"\\{exc\\}","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"tools/video/seedance_ark.py","lineNumber":1370,"sourceCode":"\n    @staticmethod\n    def _raise_for_status(response: Any) -> None:\n        try:\n            response.raise_for_status()\n        except Exception as exc:\n            detail = \"\"\n            try:\n                payload = response.json()\n                error = payload.get(\"error\") if isinstance(payload, dict) else None\n                if isinstance(error, dict):\n                    detail = \": \".join(\n                        str(error.get(key))\n                        for key in (\"code\", \"message\")\n                        if error.get(key)\n                    )\n            except Exception:\n                pass\n            raise RuntimeError(f\"{exc}\" + (f\"; {detail}\" if detail else \"\")) from exc\n\n    @staticmethod\n    def _task_error(task: dict[str, Any]) -> str:\n        error = task.get(\"error\")\n        if isinstance(error, dict):\n            return \": \".join(\n                str(error.get(key)) for key in (\"code\", \"message\") if error.get(key)\n            )\n        return str(error or \"\")\n\n    def _cost_from_task_cny(\n        self, task: dict[str, Any], inputs: dict[str, Any]\n    ) -> float | None:\n        usage = task.get(\"usage\") or {}\n        tokens = usage.get(\"completion_tokens\")\n        if (\n            not isinstance(tokens, (int, float))\n            or not math.isfinite(float(tokens))","sourceCodeStart":1352,"sourceCodeEnd":1388,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/video/seedance_ark.py#L1352-L1388","documentation":"RuntimeError raised by _raise_for_status when an Ark HTTP response has a non-2xx status. It re-raises the original requests error message (from response.raise_for_status()), augmented with the API's own error code/message parsed from the JSON body when present. This is the single funnel for all HTTP-level failures in the client, so the f-string '{exc}' is the carrier of the underlying detail (e.g. '404 Client Error: ... ; AccessKeyNotFound: invalid api key').","triggerScenarios":"Any 4xx/5xx from Ark: 401/403 bad or unscoped API key, 404 wrong base URL or unknown model/task endpoint, 400 schema violations that escaped client-side validation, 429 quota exhausted after retries are spent.","commonSituations":"Expired or wrong-environment ARK_API_KEY, using a model name not enabled on the account, region mismatch between key and base URL, or month-end quota exhaustion.","solutions":["Read the '; code: message' suffix in the error text — it is Ark's own reason and points at the fix.","401/403: verify the API key environment variable and that the key has Seedance/Ark permissions.","404: check _get_base_url() and the model identifier against current Ark docs.","429: reduce concurrency or request quota increase; do not shrink retry backoff.","400: dump the request payload and compare against the Ark request schema for that endpoint."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import os\nassert os.environ.get(\"ARK_API_KEY\"), \"ARK_API_KEY not set — expect 401 from Ark\"","typeGuard":null,"tryCatchPattern":"try:\n    result = tool.run(inputs)\nexcept RuntimeError as e:\n    text = str(e)\n    if \"429\" in text:\n        backoff_and_retry_later()\n    elif \"401\" in text or \"403\" in text or \"AccessKey\" in text:\n        raise ConfigError(\"Ark credentials invalid: \" + text)\n    else:\n        raise","preventionTips":["Always read the '; code: message' suffix — it is Ark's authoritative reason.","Validate credentials and base URL at startup with a cheap call rather than at first generation.","Track quota month-to-month to anticipate 429s."],"tags":["network","seedance","ark","http","api-errors"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}