{"record":{"id":"c2029ec29e4e30d3","repo":"langgenius/dify","slug":"deployfailed","errorCode":"deployFailed","errorMessage":"deployFailed","messagePattern":"deployFailed","errorType":"error_code","errorClass":"CreateDeploymentGuideSubmissionBlockedError","httpStatus":null,"severity":"error","filePath":"web/features/deployments/create-guide/state/submission.ts","lineNumber":168,"sourceCode":"        }\n      }\n\n      if (!get(canDeployAtom)) return undefined\n\n      set(isCreatingDeploymentAtom, true)\n\n      try {\n        const selectedEnvironmentIdentifier = selectedEnvironmentId.trim()\n        const freshSelectedEnvironment =\n          selectedEnvironment ||\n          (selectedEnvironmentIdentifier\n            ? (await deployableEnvironmentsQuery.refetch()).data?.environments.find((environment) =>\n                environmentMatchesIdentifier(environment, selectedEnvironmentIdentifier),\n              )\n            : undefined)\n        const targetEnvironmentId = freshSelectedEnvironment?.id\n        if (!targetEnvironmentId)\n          throw new CreateDeploymentGuideSubmissionBlockedError('deployFailed')\n\n        if (!get(requiredBindingsReadyAtom)) throw new Error('Missing required deployment binding.')\n        if (!get(requiredEnvVarsReadyAtom))\n          throw new Error('Missing required deployment environment variable.')\n\n        const envVars = envVarSlots.flatMap((slot) => envVarInput(slot, envVarValues[slot.key]))\n        const commonDeploymentRequest = {\n          newAppInstance: {\n            displayName: submittedInstanceName,\n            description: get(instanceDescriptionAtom).trim() || undefined,\n          },\n          environmentId: targetEnvironmentId,\n          releaseName: submittedReleaseName,\n          releaseDescription: submittedReleaseDescription || undefined,\n          credentials: selectedDeploymentRuntimeCredentials(bindingSlots, bindingSelections),\n          envVars,\n          idempotencyKey: createDeploymentIdempotencyKey(),\n          expectedDslDigest: deploymentOptions?.dslDigest,","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/web/features/deployments/create-guide/state/submission.ts#L150-L186","documentation":"Thrown by the deployment creation guide submission flow when the target deployment environment cannot be resolved to an id. The code first tries the already-selected environment object, then falls back to refetching the deployable environments list and matching by identifier; if neither yields an id, submission is blocked with the 'deployFailed' reason. It is a CreateDeploymentGuideSubmissionBlockedError, a typed sentinel used to distinguish user-blocking conditions from unexpected runtime errors.","triggerScenarios":"Triggered when selectedEnvironment is undefined AND selectedEnvironmentId is empty/whitespace, OR when the identifier is set but no environment in the refetched deployableEnvironmentsQuery result matches via environmentMatchesIdentifier. Also fires if the refetch returns no data (network/permissions failure returning undefined).","commonSituations":"The user opened the deployment guide, an admin deleted or revoked access to the selected environment between page load and submit, the environment list API call failed/returned empty due to auth expiry, or the selectedEnvironmentId stale state no longer corresponds to any deployable environment.","solutions":["Verify the user still has access to the target environment by re-checking deployableEnvironmentsQuery data and the selectedEnvironmentId value in DevTools state.","Ensure selectedEnvironment is passed into the submission when the caller already holds it, rather than relying solely on identifier re-resolution.","If the refetch is failing, inspect the network tab for 401/403 on the deployable environments endpoint and re-authenticate.","Guard the submit button with canDeployAtom so this path is unreachable when no environment is selected."],"exampleFix":"// before\nconst targetEnvironmentId = freshSelectedEnvironment?.id\nif (!targetEnvironmentId)\n  throw new CreateDeploymentGuideSubmissionBlockedError('deployFailed')\n\n// after - surface a recoverable user message instead of a bare sentinel\nconst targetEnvironmentId = freshSelectedEnvironment?.id\nif (!targetEnvironmentId) {\n  set(submissionErrorAtom, {\n    kind: 'environment-unavailable',\n    selectedIdentifier: selectedEnvironmentIdentifier,\n  })\n  throw new CreateDeploymentGuideSubmissionBlockedError('deployFailed')\n}","handlingStrategy":"validation","validationCode":"// Validate environment is resolvable before invoking submission\nfunction useEnvironmentResolvable(selectedEnvironment, selectedEnvironmentId, environments) {\n  if (selectedEnvironment?.id) return true\n  const id = selectedEnvironmentId?.trim()\n  if (!id || !environments?.length) return false\n  return environments.some((e) => environmentMatchesIdentifier(e, id))\n}\n// gate: if (!useEnvironmentResolvable(...)) return","typeGuard":"function isResolvableEnvironment(env: unknown): env is { id: string } {\n  return !!env && typeof env === 'object' && typeof (env as { id?: unknown }).id === 'string' && !!(env as { id: string }).id\n}","tryCatchPattern":"try {\n  await submit()\n} catch (e) {\n  if (e instanceof CreateDeploymentGuideSubmissionBlockedError && e.code === 'deployFailed') {\n    showToast('The selected environment is no longer available. Please choose another.')\n    return\n  }\n  throw e\n}","preventionTips":["Drive the submit button's disabled state from the same environment-resolution derivation used at submit time.","Pass selectedEnvironment through to the submit function when already held, instead of relying on re-resolution.","Refetch and re-validate environments on focus/visibilitychange to catch deletion by an admin.","Surface a clear UI message when the selected environment disappears from the list."],"tags":["frontend","deployment","state-management","jotai","environment-resolution"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}