Symptom
You delete a LangGraph deployment from the LangSmith UI in a self-hosted cluster. The UI reports success, but pods in the deployment's namespace stay running (often in CrashLoopBackOff). Deployments, ReplicaSets, Services, and ScaledObjects for that deployment also remain.
Cause
Self-hosted LangGraph deployments are represented in the cluster by a LangGraphPlatformServer Custom Resource (kind lgp, plural lgps). The langsmith-operator watches these CRs and owns the lifecycle of all child Kubernetes objects. The normal flow is: UI delete triggers CR deletion, the operator's reconcile loop runs, and every owned resource is torn down.
Orphans appear when that chain breaks, in one of three ways:
The UI delete never reached the CR. The
lgpstill exists with no deletion timestamp and no finalizers, so the operator never got a signal to clean up. This is the most common case.The CR has a deletion timestamp but the operator's reconcile loop is stalled (for example on a permissions error), so finalizer cleanup never completes.
The CR is already gone but child resources were not fully torn down, leaving true orphans with no owner.
Resolution
1. Check whether the CR still exists
kubectl get lgps -n <namespace>This only shows name and age. It does not tell you whether a deletion is in progress, so continue to the next step.
2. Inspect the CR for a deletion timestamp and finalizers
kubectl describe lgp <cr-name> -n <namespace>No
Deletion Timestampand noFinalizers: the delete never reached the CR. Go to step 4.Deletion Timestamppresent: a delete was issued but is stuck. Restart the operator pod to unstick the reconcile loop so finalizer cleanup can complete:kubectl rollout restart deploy/langsmith-operator -n <namespace>
3. Check operator logs for reconcile activity
kubectl logs -n <namespace> deploy/langsmith-operator --tail=200 | grep -i "reconcil\|error"
kubectl logs -n <namespace> deploy/langsmith-operator --tail=500 | grep -i "<cr-name>"Scoping the second command to the CR name confirms whether the operator has seen that specific deployment at all.
4. Manually delete the CR
If no deletion was ever issued, trigger the operator's cleanup loop directly:
kubectl delete lgp <cr-name> -n <namespace>5. Verify and clean up any remaining orphans
kubectl get pods,svc,scaledobject -n <namespace> | grep <cr-name>Empty output means cleanup is complete. Anything still listed has no owner and is safe to delete directly:
kubectl delete svc <name> -n <namespace>
kubectl delete scaledobject <name> -n <namespace>
kubectl delete pod <name> -n <namespace>