different-ai/openwork · error · DenApiError

invalid_session_payload

invalid_session_payload

Error message

Session response did not include a user.

What it means

After fetching /v1/me, the client validates that the payload contains a recognizable user object via getUser. If the session response has no user, it throws a 500 DenApiError with code "invalid_session_payload". This protects callers from using a malformed or unexpected session payload.

Source

Thrown at apps/app/src/app/lib/den.ts:2963

      );
    },

    async signOut() {
      await requestJson<unknown>(baseUrls, "/api/auth/sign-out", {
        method: "POST",
        token,
        body: {},
      });
    },

    async getSession(): Promise<DenUser> {
      const payload = await requestJson<unknown>(baseUrls, "/v1/me", {
        method: "GET",
        token,
      });
      const user = getUser(payload);
      if (!user) {
        throw new DenApiError(500, "invalid_session_payload", "Session response did not include a user.");
      }
      return user;
    },

    async getAppVersionMetadata(): Promise<DenAppVersionMetadata> {
      const payload = await requestJson<unknown>(baseUrls, "/v1/app-version", {
        method: "GET",
      });
      const appVersionMetadata = getDenAppVersionMetadata(payload);
      if (!appVersionMetadata) {
        throw new DenApiError(500, "invalid_app_version_payload", "App version response was missing version details.");
      }
      return appVersionMetadata;
    },

    async getDesktopConfig(orgId?: string | null): Promise<DenDesktopConfig> {
      const payload = await requestJson<unknown>(baseUrls, "/v1/me/desktop-config", {
        method: "GET",

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Verify baseUrl/apiBaseUrl points at a compatible Den server and re-authenticate
  2. Log the raw /v1/me payload to see what was actually returned
  3. Check for proxy/VPN interference returning non-JSON bodies
  4. Upgrade the server or client so both agree on the session schema

Example fix

// before
const user = await client.getMe();
// after
let user;
try { user = await client.getMe(); }
catch (err) {
  if (err instanceof DenApiError && err.code === "invalid_session_payload") await reauthenticate();
  else throw err;
}
Defensive patterns

Strategy: type-guard

Validate before calling

const res = await fetch(`${baseUrl}/v1/me`, { headers: { authorization: `Bearer ${token}` } });
const contentType = res.headers.get("content-type") ?? "";
if (!contentType.includes("application/json")) throw new Error("Den /v1/me did not return JSON");

Type guard

const isDenUser = (u: unknown): u is DenUser =>
  typeof u === "object" && u !== null && "id" in u && typeof (u as { id: unknown }).id === "string";

Try / catch

try {
  user = await client.getMe();
} catch (err) {
  if (err instanceof DenApiError && err.code === "invalid_session_payload") {
    await reauthenticate();
    user = await client.getMe();
  } else throw err;
}

Prevention

When it happens

Trigger: GET /v1/me returns 2xx but the body lacks a user object — e.g. a proxy/gateway returning HTML, a wrong server on the configured baseUrl, or a server version returning a different schema.

Common situations: Pointing the app at a non-Den server or outdated server, a reverse proxy auth page intercepting the request, or a valid token against an incompatible API version.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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