{"record":{"id":"3e429d58dba78423","repo":"harry0703/MoneyPrinterTurbo","slug":"sonilo-video-to-music-service-is-not-available-for","errorCode":null,"errorMessage":"Sonilo video-to-music service is not available for this key","messagePattern":"Sonilo video-to-music service is not available for this key","errorType":"exception","errorClass":"SoniloError","httpStatus":null,"severity":"error","filePath":"app/services/sonilo.py","lineNumber":119,"sourceCode":"            f\"Sonilo connection failed ({response.status_code}): \"\n            f\"{_safe_response_error(response)}\"\n        )\n    try:\n        payload = response.json()\n    except ValueError as exc:\n        raise SoniloError(\"Sonilo returned an invalid service response\") from exc\n    if not isinstance(payload, dict):\n        raise SoniloError(\"Sonilo returned an unexpected service response\")\n    available_services = payload.get(\"available_services\")\n    if not isinstance(available_services, list) or not all(\n        isinstance(service_id, str) for service_id in available_services\n    ):\n        raise SoniloError(\"Sonilo returned an invalid service list\")\n    normalized_services = {\n        _normalize_service_id(service_id) for service_id in available_services\n    }\n    if VIDEO_TO_MUSIC_SERVICE_ID not in normalized_services:\n        raise SoniloError(\"Sonilo video-to-music service is not available for this key\")\n    logger.info(\"Sonilo connection test succeeded\")\n    return payload\n\n\ndef _remove_file(file_path: str) -> None:\n    \"\"\"尽力清理 Sonilo 中间文件，不覆盖调用方正在处理的原始异常。\"\"\"\n    if not file_path or not os.path.exists(file_path):\n        return\n    try:\n        os.remove(file_path)\n    except OSError as exc:\n        logger.warning(\n            f\"failed to remove Sonilo temporary file: path={file_path}, error={exc}\"\n        )\n\n\ndef _create_video_proxy(video_path: str) -> str:\n    \"\"\"","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/harry0703/MoneyPrinterTurbo/blob/1f9f19c2021a68d04df228f33e9099a0c947f6f8/app/services/sonilo.py#L101-L137","documentation":"Raised by the Sonilo connection test when the service list parsed successfully but does not contain the video-to-music service after normalization (ids are lowercased and dashes converted to underscores, so video-to-music and video_to_music both match). This means the account or key genuinely lacks access to the endpoint this integration depends on; it is not a parsing problem.","triggerScenarios":"Calling the connection test with an API key whose Sonilo plan does not include video-to-music: available_services comes back listing only other services such as text_to_speech or voice_clone. Also occurs with a key from a different environment (staging key against production) or a key whose subscription lapsed so the services endpoint reflects the downgraded plan.","commonSituations":"Free-tier or trial key that never had video-to-music entitlements; subscription expired mid-cycle; using the wrong key after rotating credentials; provider temporarily disables the service for the account.","solutions":["Log in to the Sonilo dashboard and verify the key's plan includes video_to_music; upgrade or enable the service if missing.","Confirm the key configured in the WebUI (config sonilo_api_key) or the SONILO_API_KEY environment variable is the one you think it is; re-run the test with a freshly copied key.","Check for an environment mismatch (staging vs production base URL in sonilo_base_url) and point the test at the environment where the key is provisioned.","If the dashboard shows the service active but the API disagrees, contact Sonilo support; the entitlement data is server-side."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# before starting any video-to-music task, run the connection test\n# it raises this exact error when the key lacks the entitlement\nsonilo.test_connection()  # cheap; do it once at task submission","typeGuard":null,"tryCatchPattern":"try:\n    sonilo.test_connection()\nexcept SoniloError as exc:\n    if \"not available for this key\" in str(exc):\n        # entitlement problem: retrying with the same key cannot help\n        disable_sonilo_and_fallback(exc)\n    raise","preventionTips":["Run the connection test from the WebUI immediately after saving any new sonilo_api_key.","Schedule a periodic test_connection so a lapsed plan surfaces before user tasks fail."],"tags":["sonilo","api-key","entitlement","configuration"],"backgroundTag":null,"analyzedSha":"1f9f19c2021a68d04df228f33e9099a0c947f6f8","analyzedAt":"2026-08-14T19:41:05.568Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}