{"record":{"id":"8826c1c5c5a4d2f9","repo":"Significant-Gravitas/AutoGPT","slug":"str-e-8826c1","errorCode":null,"errorMessage":"str(e)","messagePattern":"str\\(e\\)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"autogpt_platform/backend/backend/api/features/postmark/postmark.py","lineNumber":44,"sourceCode":"logger = logging.getLogger(__name__)\nsettings = Settings()\n\nrouter = APIRouter()\n\npostmark_api_key_auth = APIKeyAuthenticator(\n    \"X-Postmark-Webhook-Token\",\n    settings.secrets.postmark_webhook_token,\n)\n\n\n@router.post(\"/unsubscribe\", summary=\"One Click Email Unsubscribe\")\nasync def unsubscribe_via_one_click(token: Annotated[str, Query()]):\n    logger.info(\"Received unsubscribe request from One Click Unsubscribe\")\n    try:\n        await unsubscribe_user_by_token(token)\n    except Exception as e:\n        logger.exception(\"Unsubscribe failed: %s\", e)\n        raise HTTPException(\n            status_code=500,\n            detail={\"message\": str(e), \"hint\": \"Verify Postmark token settings.\"},\n        )\n    return JSONResponse(status_code=200, content={\"status\": \"ok\"})\n\n\n@router.post(\n    \"/\",\n    dependencies=[Security(postmark_api_key_auth)],\n    summary=\"Handle Postmark Email Webhooks\",\n)\nasync def postmark_webhook_handler(\n    webhook: Annotated[\n        PostmarkWebhook,\n        Body(discriminator=\"RecordType\"),\n    ]\n):\n    logger.info(f\"Received webhook from Postmark: {webhook}\")","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/postmark/postmark.py#L26-L62","documentation":"A 500 from the Postmark one-click unsubscribe endpoint when unsubscribe_user_by_token raises any exception. The detail embeds str(e), so the concrete cause is typically an invalid/expired unsubscribe token, a missing user preference record, or a Postmark settings problem — visible in the message and in the logged traceback.","triggerScenarios":"POST /api/unsubscribe?token=... with a token that fails validation, is expired, doesn't map to a subscription, or when the unsubscribe routine hits a DB error. Postmark's webhook/one-click flow hitting the endpoint after tokens were rotated also triggers it.","commonSituations":"Old emails containing tokens invalidated by a key/secret rotation; postmark_webhook_token or related settings misconfigured; database unreachable when persisting the preference; token URL-mangled by mail clients (truncated or HTML-escaped).","solutions":["Inspect the response message and the logged 'Unsubscribe failed' traceback to identify the exact failure.","If the token is expired/invalid, regenerate the unsubscribe link or unsubscribe via the app's account settings page.","Verify Postmark-related secrets/settings (settings.secrets.postmark_webhook_token etc.) are set for the environment.","URL-decode the token exactly as sent and confirm it isn't truncated by the mail client."],"exampleFix":"# before — token from an old email\ncurl -X POST 'https://app.example.com/api/unsubscribe?token=stale-token'\n# after — fresh link from a current email\ncurl -X POST 'https://app.example.com/api/unsubscribe?token=<token-from-latest-email>'","handlingStrategy":"try-catch","validationCode":"// Check token shape before calling\nif (!/^[A-Za-z0-9_-]{20,}$/.test(token)) {\n  throw new Error('malformed unsubscribe token');\n}","typeGuard":"const isValidTokenShape = (t: string) => /^[A-Za-z0-9_-]{20,}$/.test(t);","tryCatchPattern":"try { await unsubscribe(token); }\ncatch (e) {\n  if (e.status === 500 && /expired|invalid/i.test(e.detail?.message ?? '')) {\n    showManualUnsubscribeFallback(); // account-settings link\n  } else throw e;\n}","preventionTips":["Don't leak str(e) to respondents — it may expose internals; return a generic message.","Version unsubscribe tokens so rotations are detectable, and keep old tokens honoring 'unsubscribe intent' where feasible.","URL-decode tokens exactly; validate length/format at the route boundary."],"tags":["postmark","email","unsubscribe","http-500","exception-leak"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}