different-ai/openwork · error · Error

API key was created, but the secret was not returned.

Error message

API key was created, but the secret was not returned.

What it means

handleCreate in the API keys screen POSTs to create a key. Creating a secret API key is only useful once: the server must return the plaintext secret in the creation response. getCreatedKey(payload) failing means the 2xx response did not contain the expected key object, so the one-time secret is unrecoverable and the client refuses to show a fake success.

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_components/api-keys-screen.tsx:185

                        `/v1/api-keys`,
                        {
                            method: "POST",
                            body: JSON.stringify({ name }),
                        },
                        12000,
                    );

                    if (!response.ok) {
                        throw getRequestError(
                            payload,
                            response,
                            `Failed to create API key (${response.status}).`,
                        );
                    }

                    const nextKey = getCreatedKey(payload);
                    if (!nextKey) {
                        throw new Error(
                            "API key was created, but the secret was not returned.",
                        );
                    }

                    setCreatedKey(nextKey);
                    setCreatedKeyName(name);
                    setName("");
                    setShowCreateForm(false);
                    await loadApiKeys();
                } finally {
                    setCreating(false);
                }
            });
        } catch (nextError) {
            setError(
                nextError instanceof Error
                    ? nextError.message
                    : "Failed to create API key.",

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Check the network tab for the actual create-key response body and compare with getCreatedKey's expected shape.
  2. Align server and client versions so the create response includes the secret field exactly once.
  3. If the response uses a wrapper (e.g. {key:{...}}), update getCreatedKey to unwrap it.
  4. Retry key creation; if the secret was consumed server-side, delete the orphaned key and create a new one.

Example fix

// before
const nextKey = getCreatedKey(payload);
if (!nextKey) throw new Error("API key was created, but the secret was not returned.");
// after
const raw = payload?.key ?? payload?.data?.key ?? payload;
const nextKey = getCreatedKey({ key: raw });
if (!nextKey) throw new Error("API key was created, but the secret was not returned.");
Defensive patterns

Strategy: validation

Validate before calling

function hasCreatedKey(p: unknown): boolean {
  return typeof p === "object" && p !== null &&
    ("key" in p || ("secret" in p)) && typeof (p as {secret?:unknown}).secret === "string";
}
if (!hasCreatedKey(payload)) { /* abort before showing created dialog */ }

Type guard

function isCreatedKey(k: unknown): k is { id: string; secret: string } {
  return typeof k === "object" && k !== null && typeof (k as {secret?:unknown}).secret === "string";
}

Try / catch

try {
  await handleCreate(name);
} catch (err) {
  if (err instanceof Error && err.message.includes("secret was not returned")) {
    showToast("Key was created but the secret wasn't shown — delete it and create a new one.");
  } else throw err;
}

Prevention

When it happens

Trigger: The create-key endpoint returns 2xx with an empty body or an envelope the client doesn't recognize; the server redacts the secret field for security; a proxy rewrites the response; server/client version mismatch after an API change.

Common situations: Self-hosted Den server running an older version whose create-key response omits the secret; a hardened server config that suppresses secret echo; intercepting middleware returning {id,name} only.

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/be92a8de4b18e11b. Report an issue: GitHub.