# Ошибки и решения > Сюда записываем проблемы с которыми столкнулись и как их решили. ## Шаблон записи ``` ## YYYY-MM-DD — Короткое описание проблемы **Проблема:** ... **Причина:** ... **Решение:** ... ``` ## 2026-03-07 — kaniko: unsupported protocol scheme "" **Проблема:** kaniko Job падает с `unsupported protocol scheme ""` при доступе к S3. **Причина:** В env `S3_ENDPOINT` передавался хост без схемы (`s3.msk-1.ngcloud.ru`), kaniko ожидает полный URL. **Решение:** В `builder.go` добавить `"https://" + b.s3Endpoint` при формировании env для kaniko. Также добавить `S3_FORCE_PATH_STYLE=true` — Ceph требует path-style URLs. --- ## 2026-03-07 — Бесконечный цикл сборки (94 job'а) **Проблема:** После upload оператор создавал сотни kaniko Job'ов. **Причина:** Upload handler вызывал `Status().Update(phase=Pending)` ПОСЛЕ того как контроллер уже выставил `Building`. Контроллер видел `Pending` → создавал новый Job, upload снова сбрасывал → цикл. **Решение:** 1. `startBuild()` СНАЧАЛА ставит аннотацию `last-built-s3key = spec.S3Key` (idempotency guard), затем обновляет статус. 2. Reconcile запускает сборку только если `spec.S3Key != annotations["last-built-s3key"]`. 3. Upload handler убран `Status().Update()` — контроллер сам управляет фазой. 4. `IsAlreadyExists` при создании Job не считается ошибкой (parallel reconcile). --- ## 2026-03-07 — upload.go: "object has been modified; please apply your changes" **Проблема:** `terraform apply` падал при попытке upload кода функции: ``` status 500: {"error":"update function: Operation cannot be fulfilled on functions.sless.kube5s.ru "pg-query": the object has been modified; please apply your changes to the latest version and try again"} ``` **Причина:** В `upload.go` использовался `h.K8s.Update(ctx, fn)`. Между `Get()` и `Update()` контроллер успевал изменить объект (выставить статус/аннотации) — `resourceVersion` в памяти устаревал, API-сервер отклонял обновление. **Решение:** Заменить `Update` на `Patch` (strategic merge patch): ```go patch := client.MergeFrom(fn.DeepCopy()) fn.Spec.S3Key = s3Key fn.Spec.S3Bucket = h.S3.Bucket() h.K8s.Patch(ctx, fn, patch) ``` `MergePatch` передаёт только изменённые поля и не требует точного `resourceVersion`. --- ## 2026-03-07 — Terraform Provider: "provider produced inconsistent result" для schedule **Проблема:** При создании `sless_trigger` с `type=http` (без поля `schedule`) terraform падал: ``` .schedule: was null, but now cty.StringVal("") ``` **Причина:** В `trToModel()` провайдера `Schedule` всегда возвращался как `types.StringValue(tr.Schedule)`. Если schedule не задан, API возвращает пустую строку `""`, провайдер сохранял `""` в state. Terraform видел расхождение: в плане было `null` (поле не задано в HCL), в state после apply стало `""`. **Решение:** В `trToModel()` возвращать `types.StringNull()` когда schedule пустая строка: ```go schedule := types.StringNull() if tr.Schedule != "" { schedule = types.StringValue(tr.Schedule) } ``` Правило: для `Optional` computed-полей пустая строка из API → `null` в state. --- ## 2026-03-07 — Terraform Provider: "Resource Import Not Implemented" **Проблема:** После failed `terraform apply` (Function создалась, Trigger упал) state не содержал созданных ресурсов. Повторный apply падал с `status 409: function already exists`. `terraform import` тоже не работал: ``` This resource does not support import. Please contact the provider developer ``` **Причина:** В провайдере не реализован `ImportState` для ресурса `sless_function`. **Решение (краткосрочное):** Удалить ресурсы из кластера вручную (`kubectl delete`) и повторить apply с чистым state. **Решение (долгосрочное / TODO):** Реализовать `ImportState` для `sless_function` и `sless_trigger`: ```go func (r *FunctionResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { // ID формат: "namespace/name" resource.ImportStatePassthroughID(ctx, path.Root("name"), req, resp) } ``` --- ## 2026-03-07 — handler.py: column "started_at" does not exist **Проблема:** При вызове функции pg-query в логах пода: ``` psycopg2.errors.UndefinedColumn: column "started_at" does not exist ``` **Причина:** В `examples/pg-query/handler.py` использовалось имя колонки `started_at`, но в схеме `migrations/001_initial.sql` таблицы `invocations` колонка называется `created_at`. **Решение:** Исправить `select` и `dict()` в handler.py: `started_at` → `created_at`. **Урок:** При написании примеров всегда сверяться со схемой в `migrations/`. --- ## 2026-03-07 — Deployment не перезапустил pod после re-build образа **Проблема:** После `terraform apply` (re-upload + kaniko пересборка) pod продолжал использовать старый код — `curl` возвращал ошибку `started_at`. **Причина:** Образ тегируется как `:latest`. Kubernetes не перезапускает pod автоматически если тег не изменился — даже если образ на DockerHub обновился. `imagePullPolicy` по умолчанию `IfNotPresent` для non-digest образов, только `Always` гарантирует pull при каждом запуске. **Решение (краткосрочное):** Явный `kubectl rollout restart deployment/pg-query -n sless-fn-default`. **Решение (долгосрочное / TODO):** В `function_controller.go` после успешной сборки добавить `rollout restart` аннотацию: ```go // Форсируем rollout через аннотацию kubectl.kubernetes.io/restartedAt deployment.Spec.Template.Annotations["kubectl.kubernetes.io/restartedAt"] = time.Now().Format(time.RFC3339) ``` Либо использовать версионированные теги образов вместо `:latest` (`:v{timestamp}`). --- ## 2026-03-07 — Docker credStore: exec "docker-credential-desktop.exe" **Проблема:** `docker push` падал с `exec: "docker-credential-desktop.exe": executable file not found`. **Причина:** В `~/.docker/config.json` осталась запись `"credsStore": "desktop.exe"` от Docker Desktop. **Решение:** Удалить поле `credsStore` из `~/.docker/config.json`, оставить только `auths` с base64 credentials. --- ## 2026-03-07 — controller-gen v0.11.1 паникует с Go 1.23 **Проблема:** `operator-sdk create api` падает с panic в `controller-gen` при `make generate`. **Причина:** controller-tools v0.11.1 несовместим с Go 1.23 (nil pointer dereference в go/types). **Решение:** В `Makefile` заменить `CONTROLLER_TOOLS_VERSION ?= v0.11.1` на `v0.14.0`. ---