TryGhost/Ghost · error · Error

Failed to update member

Error message

Failed to update member

What it means

updateMember in comments-ui actions.ts calls api.member.update(patchData) which PUTs to the members/api/member endpoint. The api.member.update implementation (api.ts:99-104) returns null when the response is not ok. updateMember then checks `if (!member)` and throws this error. The surrounding try/catch catches it and returns {success: false, error: err} — so the error never rejects the action promise; it is surfaced as a failure result.

Source

Thrown at apps/comments-ui/src/actions.ts:625

    const patchData: {name?: string, expertise?: string} = {};

    const originalName = state?.member?.name;

    if (name && originalName !== name) {
        patchData.name = name;
    }

    const originalExpertise = state?.member?.expertise;
    if (expertise !== undefined && originalExpertise !== expertise) {
        // Allow to set it to an empty string or to null
        patchData.expertise = expertise;
    }

    if (Object.keys(patchData).length > 0) {
        try {
            const member = await api.member.update(patchData);
            if (!member) {
                throw new Error('Failed to update member');
            }
            return {
                member,
                success: true
            };
        } catch (err) {
            return {
                success: false,
                error: err
            };
        }
    }
    return null;
}

function openPopup({data}: {data: Page}) {
    return {
        popup: data

View on GitHub (pinned to 47d8b0e2ad)

Solutions

  1. Check the Network tab for the PUT members/api/member request status code to identify the cause (401 auth, 422 validation, 500 server).
  2. If 401, re-fetch the member identity/session and prompt re-authentication before retrying the update.
  3. Validate name/expertise client-side (non-empty name, reasonable length) before calling updateMember to avoid 422s.
  4. Handle the {success: false, error} return in the UI to show a user-facing message rather than silently failing.
Defensive patterns

Strategy: try-catch

Validate before calling

function isMemberUpdatePayloadValid(data: {name?: string, expertise?: string}): boolean {
  if (data.name !== undefined && (typeof data.name !== 'string' || data.name.length === 0 || data.name.length > 255)) {
    return false;
  }
  if (data.expertise !== undefined && data.expertise !== null && (typeof data.expertise !== 'string' || data.expertise.length > 200)) {
    return false;
  }
  return true;
}

Try / catch

// updateMember already wraps in try/catch and returns {success, error}; consume it:
const result = await updateMember({data, state, api});
if (result && !result.success) {
  // show the error to the user; if err is the 'Failed to update member' Error,
  // the PUT returned non-ok — likely auth or validation
}

Prevention

When it happens

Trigger: The member PUT returns a non-2xx status. The member is not authenticated (session cookie missing/expired yields 401), the expertise or name field fails server-side validation (422), the member record was deleted (404), or the server errors (5xx). Because api.member.update swallows the HTTP status and returns null, the caller cannot distinguish these causes from the thrown error alone.

Common situations: A member's session expires while the comments UI is open and they edit their profile. The expertise field exceeds a server-side length limit. A network hiccup returns a 502 and the member retry hits a stale session.

Related errors


AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13). Data as JSON: /api/errors/3e9527055f06465c. Report an issue: GitHub.