{"record":{"id":"fdd24784a4041371","repo":"FujiwaraChoki/MoneyPrinterV2","slug":"post-bridge-did-not-return-a-media-id-and-upload-u","errorCode":null,"errorMessage":"Post Bridge did not return a media_id and upload_url.","messagePattern":"Post Bridge did not return a media_id and upload_url\\.","errorType":"error_code","errorClass":"PostBridgeClientError","httpStatus":null,"severity":"error","filePath":"src/classes/PostBridge.py","lineNumber":119,"sourceCode":"        file_name = os.path.basename(file_path)\n        mime_type = self._guess_mime_type(file_path)\n        file_size = os.path.getsize(file_path)\n\n        upload_response = self._request_json(\n            \"POST\",\n            f\"{self.API_BASE}/media/create-upload-url\",\n            json={\n                \"name\": file_name,\n                \"mime_type\": mime_type,\n                \"size_bytes\": file_size,\n            },\n        )\n\n        media_id = upload_response.get(\"media_id\")\n        upload_url = upload_response.get(\"upload_url\")\n\n        if not media_id or not upload_url:\n            raise PostBridgeClientError(\n                \"Post Bridge did not return a media_id and upload_url.\"\n            )\n\n        with open(file_path, \"rb\") as media_file:\n            self._request(\n                \"PUT\",\n                upload_url,\n                data=media_file,\n                headers={\"Content-Type\": mime_type},\n                timeout=600,\n                expected_statuses={200, 201},\n                use_default_headers=False,\n            )\n\n        return media_id\n\n    def create_post(\n        self,","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/FujiwaraChoki/MoneyPrinterV2/blob/5192af8eca97759f941834b947e3ceb209da0649/src/classes/PostBridge.py#L101-L137","documentation":"Raised by PostBridgeClient.upload_media when the media-creation response lacks media_id or upload_url. These two fields are required to know what to PUT the file bytes to, so the upload cannot proceed.","triggerScenarios":"The create-media endpoint returns an error object or partial payload with 200 status; fields renamed by a newer API version (e.g. 'id' instead of 'media_id'); or an empty dict returned on quota/auth edge cases.","commonSituations":"API schema drift after a Post Bridge update, expired/invalid API token producing a soft error, or account lacking media-upload permission so the response contains an error envelope.","solutions":["Log the full upload_response to identify the actual payload (renamed fields vs error envelope)","Update field extraction to match the current API (e.g. upload_response.get('id') as fallback)","Verify the API token and account permissions for media uploads","Handle a nested structure like upload_response['data']['media_id'] if the API wrapped the payload"],"exampleFix":"// before\nmedia_id = upload_response.get(\"media_id\")\nupload_url = upload_response.get(\"upload_url\")\n\n// after\npayload = upload_response.get(\"data\", upload_response)\nmedia_id = payload.get(\"media_id\") or payload.get(\"id\")\nupload_url = payload.get(\"upload_url\") or payload.get(\"uploadUrl\")\nif not media_id or not upload_url:\n    raise PostBridgeClientError(f\"Unexpected media payload: {upload_response!r}\")","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def has_media_upload_fields(payload: dict) -> bool:\n    data = payload.get(\"data\", payload) if isinstance(payload, dict) else {}\n    return bool(\n        isinstance(data, dict)\n        and (data.get(\"media_id\") or data.get(\"id\"))\n        and (data.get(\"upload_url\") or data.get(\"uploadUrl\"))\n    )","tryCatchPattern":"try:\n    media_id = client.upload_media(path)\nexcept PostBridgeClientError as exc:\n    if \"media_id and upload_url\" in str(exc):\n        logging.error(\"Token/permission or API version issue; check Post Bridge account\")\n    raise","preventionTips":["Log the full upload handshake response when this fires","Verify API token scopes and media permissions before upload flows","Watch Post Bridge changelogs for field renames and pin compatible API versions"],"tags":["python","api-client","json","upload"],"backgroundTag":"schema-validation-failed","analyzedSha":"5192af8eca97759f941834b947e3ceb209da0649","analyzedAt":"2026-08-28T10:31:46.474Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}