{"record":{"id":"be92a8de4b18e11b","repo":"different-ai/openwork","slug":"api-key-was-created-but-the-secret-was-not-return","errorCode":null,"errorMessage":"API key was created, but the secret was not returned.","messagePattern":"API key was created, but the secret was not returned\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/api-keys-screen.tsx","lineNumber":185,"sourceCode":"                        `/v1/api-keys`,\n                        {\n                            method: \"POST\",\n                            body: JSON.stringify({ name }),\n                        },\n                        12000,\n                    );\n\n                    if (!response.ok) {\n                        throw getRequestError(\n                            payload,\n                            response,\n                            `Failed to create API key (${response.status}).`,\n                        );\n                    }\n\n                    const nextKey = getCreatedKey(payload);\n                    if (!nextKey) {\n                        throw new Error(\n                            \"API key was created, but the secret was not returned.\",\n                        );\n                    }\n\n                    setCreatedKey(nextKey);\n                    setCreatedKeyName(name);\n                    setName(\"\");\n                    setShowCreateForm(false);\n                    await loadApiKeys();\n                } finally {\n                    setCreating(false);\n                }\n            });\n        } catch (nextError) {\n            setError(\n                nextError instanceof Error\n                    ? nextError.message\n                    : \"Failed to create API key.\",","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/api-keys-screen.tsx#L167-L203","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the network tab for the actual create-key response body and compare with getCreatedKey's expected shape.","Align server and client versions so the create response includes the secret field exactly once.","If the response uses a wrapper (e.g. {key:{...}}), update getCreatedKey to unwrap it.","Retry key creation; if the secret was consumed server-side, delete the orphaned key and create a new one."],"exampleFix":"// before\nconst nextKey = getCreatedKey(payload);\nif (!nextKey) throw new Error(\"API key was created, but the secret was not returned.\");\n// after\nconst raw = payload?.key ?? payload?.data?.key ?? payload;\nconst nextKey = getCreatedKey({ key: raw });\nif (!nextKey) throw new Error(\"API key was created, but the secret was not returned.\");","handlingStrategy":"validation","validationCode":"function hasCreatedKey(p: unknown): boolean {\n  return typeof p === \"object\" && p !== null &&\n    (\"key\" in p || (\"secret\" in p)) && typeof (p as {secret?:unknown}).secret === \"string\";\n}\nif (!hasCreatedKey(payload)) { /* abort before showing created dialog */ }","typeGuard":"function isCreatedKey(k: unknown): k is { id: string; secret: string } {\n  return typeof k === \"object\" && k !== null && typeof (k as {secret?:unknown}).secret === \"string\";\n}","tryCatchPattern":"try {\n  await handleCreate(name);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"secret was not returned\")) {\n    showToast(\"Key was created but the secret wasn't shown — delete it and create a new one.\");\n  } else throw err;\n}","preventionTips":["Test key creation against every environment (self-hosted, cloud) before release.","Never cache created keys — treat the secret as one-time and surface it immediately.","Add a schema assertion (Zod) on the create-key response in CI.","Keep getCreatedKey's unwrap logic aligned with server response version."],"tags":["api-contract","api-keys","secrets"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}