different-ai/openwork · error · Error

Profile update response did not include a user.

Error message

Profile update response did not include a user.

What it means

updateProfile in DenFlowProvider calls the Den API to update the user's profile and expects the response body to contain a user object extractable via getUser(payload). If the HTTP call succeeds but the payload lacks a recognizable user shape, this error is thrown so the app never sets an undefined user into context. It indicates an API contract mismatch between client and server.

Source

Thrown at ee/apps/den-web/app/(den)/_providers/den-flow-provider.tsx:1425

  }

  async function updateUserProfile(input: { firstName: string; lastName: string }) {
    const { response, payload } = await requestJson(
      "/v1/me/profile",
      {
        method: "PATCH",
        body: JSON.stringify(input),
      },
      12000,
    );

    if (!response.ok) {
      throw new Error(getErrorMessage(payload, `Failed to update profile (${response.status}).`));
    }

    const nextUser = getUser(payload);
    if (!nextUser) {
      throw new Error("Profile update response did not include a user.");
    }

    setUser(nextUser);
    identifyPosthogUser(nextUser);
    return nextUser;
  }

  async function launchWorker(options: { source?: "manual" | "signup_auto"; workerNameOverride?: string } = {}) {
    if (!user) {
      setAuthError("Sign in before launching a worker.");
      return "error" as const;
    }

    const resolvedLaunchName = options.workerNameOverride?.trim() || workerName.trim() || DEFAULT_WORKER_NAME;

    setLaunchBusy(true);
    setLaunchError(null);
    setOrgLimitError(null);

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Inspect the actual response payload in devtools/network tab and compare with what getUser(payload) expects (field name and shape).
  2. Check that the den-web client and den server versions match; redeploy whichever is stale.
  3. If the server intentionally returns an envelope, update getUser in the provider to unwrap it.
  4. Add a server-side fix to always return the full user object on profile update.

Example fix

// before
const nextUser = getUser(payload);
if (!nextUser) throw new Error("Profile update response did not include a user.");
// after
const rawUser = payload?.user ?? payload?.data?.user;
const nextUser = rawUser ? getUser({ user: rawUser }) : undefined;
if (!nextUser) throw new Error("Profile update response did not include a user.");
Defensive patterns

Strategy: validation

Validate before calling

function hasUser(p: unknown): boolean {
  return typeof p === "object" && p !== null && "user" in p && typeof (p as {user:unknown}).user === "object";
}
if (!hasUser(payload)) { /* don't call updateProfile-dependent UI */ }

Type guard

function isUser(u: unknown): u is { id: string; email: string } {
  return typeof u === "object" && u !== null && "id" in u && "email" in u;
}

Try / catch

try {
  await updateProfile(data);
} catch (err) {
  if (err instanceof Error && err.message.includes("did not include a user")) {
    showToast("Profile saved but response was malformed — reloading.");
    await refetchUser();
  } else throw err;
}

Prevention

When it happens

Trigger: The PUT/PATCH profile endpoint returns 2xx with an empty body, a wrapped envelope like {data:{...}} instead of {user:{...}} (or whatever getUser expects), or a partial-update response that only returns the changed fields.

Common situations: Server deployed at a different version than the web client after an API contract change; a proxy stripping or reshaping the response; hitting a mock/stub endpoint that returns {} with 200.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/63924a31864c8f16. Report an issue: GitHub.