{"record":{"id":"c26df4cf2114132f","repo":"Significant-Gravitas/AutoGPT","slug":"str-e-c26df4","errorCode":null,"errorMessage":"str(e)","messagePattern":"str\\(e\\)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"autogpt_platform/backend/backend/api/features/push/routes.py","lineNumber":51,"sourceCode":"    summary=\"Register a push subscription for the current user\",\n    status_code=HTTP_204_NO_CONTENT,\n    dependencies=[Security(requires_user)],\n)\nasync def subscribe_push(\n    user_id: Annotated[str, Security(get_user_id)],\n    body: PushSubscribeRequest,\n) -> None:\n    try:\n        await validate_push_endpoint(body.endpoint)\n        await upsert_push_subscription(\n            user_id=user_id,\n            endpoint=body.endpoint,\n            p256dh=body.keys.p256dh,\n            auth=body.keys.auth,\n            user_agent=body.user_agent,\n        )\n    except ValueError as e:\n        raise HTTPException(status_code=HTTP_400_BAD_REQUEST, detail=str(e))\n\n\n@router.post(\n    \"/unsubscribe\",\n    summary=\"Remove a push subscription\",\n    status_code=HTTP_204_NO_CONTENT,\n    dependencies=[Security(requires_user)],\n)\nasync def unsubscribe_push(\n    user_id: Annotated[str, Security(get_user_id)],\n    body: PushUnsubscribeRequest,\n) -> None:\n    await delete_push_subscription(user_id, body.endpoint)\n","sourceCodeStart":33,"sourceCodeEnd":65,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/push/routes.py#L33-L65","documentation":"A 400 from the push subscription endpoint when validate_push_endpoint or upsert_push_subscription raises ValueError — i.e. the supplied Web Push endpoint or key material is malformed. The detail carries the validation message (str(e)) describing exactly which part failed.","triggerScenarios":"POST /api/push/subscribe with an endpoint URL that isn't a valid push service URL, missing/invalid p256dh or auth keys (wrong base64url, wrong lengths), or a key format the server rejects. Typically the browser-generated PushSubscription was serialized incorrectly (e.g. keys not converted to buffers/base64 properly).","commonSituations":"Frontend sending endpoint/keys as ArrayBuffer or with base64 vs base64urlurl padding mismatches; corrupted subscription objects after browser updates; testing with hand-written payloads; proxy stripping parts of the JSON body.","solutions":["Read the 400 detail — it names the invalid field or format.","Log the outgoing subscription object client-side and verify endpoint is an https push-service URL and keys are base64url-encoded strings of the expected lengths (p256dh 65 bytes, auth 16 bytes).","Re-acquire the subscription via pushManager.subscribe() instead of persisting/reusing an old one.","If your serialization converts ArrayBuffers, apply the standard bufferToBase64Url conversion before POSTing."],"exampleFix":"// before — raw ArrayBuffer sent as {}\nbody: { endpoint: sub.endpoint, keys: { p256dh: sub.keys.p256dh, auth: sub.keys.auth } }\n// after — proper base64url strings\nconst b64 = (buf) => btoa(String.fromCharCode(...new Uint8Array(buf))).replace(/\\+/g,'-').replace(/\\//g,'_').replace(/=+$/,'');\nbody: { endpoint: sub.endpoint, keys: { p256dh: b64(sub.getKey('p256dh')), auth: b64(sub.getKey('auth')) } };","handlingStrategy":"validation","validationCode":"// Client: shape-check the subscription before subscribing\nconst b64url = (s: string) => /^[A-Za-z0-9_-]+$/.test(s);\nif (!sub.endpoint.startsWith('https://') || !b64url(sub.keys.p256dh) || !b64url(sub.keys.auth)) {\n  throw new Error('invalid push subscription payload');\n}\nawait api.post('/push/subscribe', sub);","typeGuard":"interface PushKeys { p256dh: string; auth: string }\nfunction isPushSubscription(o: unknown): o is { endpoint: string; keys: PushKeys } {\n  const p = o as any;\n  return typeof p?.endpoint === 'string' && p.endpoint.startsWith('https://')\n    && typeof p?.keys?.p256dh === 'string' && typeof p?.keys?.auth === 'string';\n}","tryCatchPattern":"try { await subscribePush(body); }\ncatch (e) {\n  if (e.status === 400) { showPushConfigError(e.detail); /* don't retry */ }\n  else throw e;\n}","preventionTips":["Convert ArrayBuffers to base64url exactly once, at acquisition time.","Re-subscribe via pushManager.subscribe() rather than reusing stored subscriptions after browser updates.","Surface the 400 detail to developers — it names the failing field."],"tags":["web-push","validation","http-400","push-notifications"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}