Skip to content

fix(member-profile): restore photo upload and fix preview ReferenceError#4267

Draft
bokelley wants to merge 2 commits intomainfrom
claude/issue-4260-member-profile-photo-upload
Draft

fix(member-profile): restore photo upload and fix preview ReferenceError#4267
bokelley wants to merge 2 commits intomainfrom
claude/issue-4260-member-profile-photo-upload

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

@bokelley bokelley commented May 8, 2026

Closes #4260

Two bugs caused profile photo uploads on /member-profile to silently revert to the default avatar after saving, with no error shown to the user.

Bug 1 — saveProfile() dropped the photo silently. The formData object never included photo_url, so all photo changes were discarded at form submission. For individual profiles the photo field maps to resolved_brand.logo_url; the fix persists a changed URL value via a direct PUT /api/me/member-profile/brand-identity call after the main profile save succeeds. The direct fetch bypasses the _brandSaving guard used by the interactive brand section. Data URLs from handleLogoUpload() are explicitly guarded: the server rejects them (checkLogoUrlIsImage requires https:, and base64 blobs exceed the 2000-char limit), so the fix surfaces a clear message — "please host your image and paste the URL" — instead of a silent 400.

Bug 2 — ReferenceError: parsed is not defined in updatePhotoPreview(). const parsed was declared inside a try {} block but referenced outside it. This threw on every profile load that had an existing photo URL (the normal case), silently breaking the preview. The fix restructures the guard to use img.src = photoUrl directly and skips URL-format validation for data: URIs so freshly-uploaded file previews also render.

Non-breaking justification: changes are confined to server/public/member-profile.html (client-side UI only). No schema, task definition, API surface, or protocol field is touched; existing consumers and callers are unaffected.

Pre-PR review:

  • code-reviewer: approved — no remaining blockers after two passes; one nit noted (partial-save cliff on new-profile if photo URL is invalid: profile is already persisted, so a retry correctly issues a PUT; behavior is acceptable and documented here)
  • internal-tools-strategist: approved — 409 handling from brand-identity endpoint is proportionate for this path (edge case; error message is actionable); full inline orphan-decision UI is out of scope for a profile-save side-call

Nits (not fixed, tracked for follow-up):

  • Preview shows data-URL image then errors on save — consider replacing preview with a static "paste a URL" message when photoUrl.startsWith('data:') to set expectations earlier
  • Error field is message; brand-identity route also returns error — consistent with existing pattern at line 2838 but worth a follow-up sweep
  • Clearing a photo (clearLogo → empty field) does not persist the clear to the server; a follow-up should send { logo_url: null } to brand-identity when the field was non-empty before

Triage-managed PR. This bot does not currently iterate on
review comments or PR conversation threads (only on the source
issue). To unblock:

  • Push fixup commits directly: gh pr checkout <num>
    fix → push.
  • Or re-trigger: comment /triage execute on the source
    issue.

See #3121
for context.

Session: https://claude.ai/code/session_01Eaet96RXhtpp46SciTWcdS


Generated by Claude Code

Two bugs caused profile photo uploads to silently revert to the default
avatar after saving:

1. `saveProfile()` never included `photo_url` in the submitted formData.
   For individual profiles the photo maps to `resolved_brand.logo_url`;
   the fix persists a changed URL value via a direct call to
   `PUT /api/me/member-profile/brand-identity` after the main profile
   save succeeds. Data URLs from the file-picker are rejected by the
   server (https-only, 2000-char limit) — the fix surfaces a clear
   message instead of a silent 400.

2. `const parsed` was declared inside a `try {}` block but referenced
   outside it, causing `ReferenceError: parsed is not defined` whenever
   the photo preview ran against a valid https URL (i.e. every profile
   load with an existing photo). The fix restructures the guard to use
   `img.src = photoUrl` directly and wraps the URL-validation block so
   data-URL previews also render after a file selection.

https://claude.ai/code/session_01Eaet96RXhtpp46SciTWcdS
@bokelley bokelley added the claude-triaged Issue has been triaged by the Claude Code triage routine. Remove to re-triage. label May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude-triaged Issue has been triaged by the Claude Code triage routine. Remove to re-triage.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Profile photo upload silently fails — reverts to avatar after save

2 participants