{"record":{"id":"22022704a3d34abe","repo":"different-ai/openwork","slug":"the-plugin-was-created-but-no-id-was-returned","errorCode":null,"errorMessage":"The plugin was created, but no id was returned.","messagePattern":"The plugin was created, but no id was returned\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ee/apps/den-web/app/(den)/dashboard/_components/plugin-editor-screen.tsx","lineNumber":221,"sourceCode":"              credentialMode: draft.credentialMode,\n              description: description.trim() || null,\n              githubUrl: draft.githubUrl,\n              marketplaceId: marketplaceId || undefined,\n              name: name.trim(),\n              selectedSkillKeys: draft.selectedSkillKeys,\n              selectedServerKeys: draft.selectedServerKeys,\n            }),\n          },\n          30000,\n        );\n        if (!result.response.ok) {\n          throw getRequestError(result.payload, result.response, \"Failed to create the imported plugin.\");\n        }\n        const item = isRecord(result.payload) && isRecord(result.payload.item) ? result.payload.item : null;\n        const plugin = item && isRecord(item.plugin) ? item.plugin : null;\n        pluginId = plugin && typeof plugin.id === \"string\" ? plugin.id : null;\n      });\n      if (!pluginId) throw new Error(\"The plugin was created, but no id was returned.\");\n\n      clearPluginImportDraft();\n      await queryClient.invalidateQueries({ queryKey: pluginQueryKeys.all });\n      router.push(getPluginRoute(orgSlug, pluginId));\n      router.refresh();\n    } catch (error) {\n      setSaveError(error instanceof Error ? error.message : \"Failed to create the imported plugin.\");\n    } finally {\n      setSaving(false);\n    }\n  }\n\n  async function createPlugin() {\n    if (!name.trim()) {\n      setSaveError(\"Give your plugin a name.\");\n      return;\n    }\n    if (importDraft) {","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/ee/apps/den-web/app/(den)/dashboard/_components/plugin-editor-screen.tsx#L203-L239","documentation":"createImportedPlugin POSTs the imported plugin and expects the response payload { item: { plugin: { id } } }. After the request succeeds (2xx) it extracts plugin.id; if the id is missing or not a string it throws this message. The plugin was actually created server-side — the failure is purely in reading the returned id, so retrying would duplicate the plugin.","triggerScenarios":"Server returns 200/201 with an unexpected payload shape: item missing, item.plugin missing, or plugin.id absent/non-string — typically a den-web/Den server API contract mismatch, a proxy stripping the body, or an empty 204 response.","commonSituations":"Self-hosted Den server version older/newer than den-web returning a different create-response envelope; a corporate proxy or auth wrapper rewriting the JSON; the endpoint changed from {item:{plugin:{id}}} to a flat shape; race where the response body was truncated.","solutions":["Inspect the create response in devtools/network to see the actual payload shape and fix the extraction path to match.","Align den-web and Den server versions so the create-plugin response contract matches.","Check for a proxy/middleware rewriting or truncating response bodies on /v1/plugins creation.","Before retrying, list plugins and reuse an existing plugin with the same name to avoid duplicates; make the server always return the id on success."],"exampleFix":"// before: single rigid extraction path, duplicate-prone retry\nconst item = isRecord(result.payload) && isRecord(result.payload.item) ? result.payload.item : null;\nconst plugin = item && isRecord(item.plugin) ? item.plugin : null;\npluginId = plugin && typeof plugin.id === \"string\" ? plugin.id : null;\nif (!pluginId) throw new Error(\"The plugin was created, but no id was returned.\");\n// after: accept alternate response shapes before giving up\nfunction extractCreatedPluginId(payload: unknown): string | null {\n  if (!isRecord(payload)) return null;\n  const item = isRecord(payload.item) ? payload.item : payload;\n  const plugin = isRecord(item.plugin) ? item.plugin : item;\n  return typeof plugin.id === \"string\" ? plugin.id : null;\n}\npluginId = extractCreatedPluginId(result.payload);\nif (!pluginId) throw new Error(\"The plugin was created, but no id was returned.\");","handlingStrategy":"validation","validationCode":"function validateCreatePluginResponse(payload: unknown): string | null {\n  if (!isRecord(payload)) return null;\n  const item = isRecord(payload.item) ? payload.item : payload;\n  const plugin = isRecord(item.plugin) ? item.plugin : item;\n  return typeof plugin.id === \"string\" && plugin.id.length > 0 ? plugin.id : null;\n}\nconst id = validateCreatePluginResponse(result.payload);\nif (!id) throw new Error(\"The plugin was created, but no id was returned.\");","typeGuard":"function isCreatePluginResponse(p: unknown): p is { item: { plugin: { id: string } } } {\n  if (!isRecord(p) || !isRecord(p.item)) return false;\n  const plugin = p.item.plugin;\n  return isRecord(plugin) && typeof plugin.id === \"string\" && plugin.id.length > 0;\n}","tryCatchPattern":"try {\n  const id = await createImportedPlugin(draft);\n  router.push(getPluginRoute(orgSlug, id));\n} catch (err) {\n  if (err instanceof MissingCreatedIdError) {\n    const existing = await findPluginByName(draft.name); // avoid duplicate on retry\n    if (existing) { router.push(getPluginRoute(orgSlug, existing.id)); return; }\n  }\n  showToast(\"The plugin may have been created but its id was not returned; check the plugin list.\");\n}","preventionTips":["Never blind-retry a create call after this error — the plugin likely exists; reconcile by name first.","Add a contract test asserting the create-plugin response envelope { item: { plugin: { id } } }.","Pin den-web and Den server versions together; validate the response shape on upgrade.","Reject empty/204 responses server-side by always returning the created plugin id."],"tags":["api-contract","den-web","plugin-creation","response-parsing"],"backgroundTag":"missing-identifier-in-response","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}