You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
NLPGO_ENGINE_CODE_BLOCK_TIMEOUT_SECONDS / the code-block timeout ceiling it controls is 600 (seconds) as an independent literal in multiple places across langwatch/langwatch and langwatch/langwatch-saas, with no shared source of truth. Nothing enforces that these stay in sync — an operator raising the ceiling in one place silently leaves the others behind, which is exactly the client/server drift bug that langwatch/langwatch#7645 exists to fix for the scenario-client vs nlpgo-server pair. That PR (still open, not merged as of this issue) only closes the drift between two of these sites; the rest are untouched.
Where 600 (or its absence) lives today
Verified live in the repos, 2026-08-28:
Go engine default — langwatch/services/nlpgo/config.go:114, CodeBlockTimeoutSeconds: 600 (also mirrored as opts.DefaultTimeout = 600 * time.Second in langwatch/services/nlpgo/app/engine/blocks/codeblock/codeblock.go:115).
Terraform, nlpgo Lambda (SaaS-wide) — langwatch-saas/infrastructure/langwatch_nlp_lambda.tf:265, same literal.
Terraform, per-project Lambda module — langwatch-saas/infrastructure/runtime/modules/langwatch-nlp-lambda/main.tf:276, same literal again (a third, separately-maintained Terraform copy).
Terraform, workers deployment — langwatch-saas/infrastructure/langwatch_workers.tf (added in https://github.com/langwatch/langwatch-saas/pull/1185), same literal, so the scenario-client process actually gets the var forwarded to it — a 4th copy.
Per-project Lambda creation code (application-level, not Terraform) — langwatch/platform/app/src/optimization_studio/server/lambda/index.ts (createLambdaFunction's Environment.Variables block, ~line 259) does not set NLPGO_ENGINE_CODE_BLOCK_TIMEOUT_SECONDS at all — these dynamically-created per-project Lambdas silently fall back to whatever in-code default nlpgo/the scenario client ship with, with zero visibility into what that resolves to per-project.
Helm chart (self-hosted) — langwatch/charts/langwatch/templates/langwatch_nlp/deployment.yaml and langwatch/charts/langwatch/values.yaml also never set this var, so a self-hosted install relies entirely on the same in-code default as Make add row/view row/edit role a drawer instead of modal #6, with the same blind spot.
TS client-side derivation (scenario client) — proposed in the still-open fix(scenarios): derive nlpgo fetch deadline from engine's own ceiling langwatch#7645, platform/app/src/server/nlpgo/timeouts.ts: reads NLPGO_ENGINE_CODE_BLOCK_TIMEOUT_SECONDS with an in-code fallback of 600 if unset. Once merged this becomes a fifth independent 600 literal (a fallback default, not a Terraform value) that must track the Go engine's.
Why this matters
None of sites 1-5 (and the future site 8) derive from a shared constant — each is a hand-copied literal. Sites 6 and 7 don't set the var at all, so they rely on the literals in 1/8 staying correct by convention. Raising the ceiling requires a human to remember to touch every one of these; missing one reintroduces exactly the "server raised, client still capped" drift that PR #7645 was written to eliminate — just at a different client (a per-project Lambda, or a self-hosted install) instead of the SaaS workers process.
Suggested fix
Introduce one shared source for the value:
Terraform side: a local.nlpgo_code_block_timeout_seconds (or equivalent) in langwatch-saas/infrastructure, referenced by all 4 Terraform sites (k8s, SaaS lambda, per-project lambda module, workers) instead of the repeated string literal.
Application side: export the Go engine's default as the canonical value (or a small shared constants file) and have code-agent.adapter.ts / timeouts.ts (once #7645 lands) import it rather than hardcoding a matching fallback.
Explicitly set the env var for the per-project Lambda creation path (lambda/index.ts) and the Helm chart, rather than leaving them on implicit in-code defaults.
Context
Deferred out of scope from https://github.com/langwatch/langwatch-saas/pull/1185, which added site #5 above (the one new env var that PR needed) but explicitly did not attempt to de-duplicate the pre-existing literal, since that touches files outside what was asked there.
Problem
NLPGO_ENGINE_CODE_BLOCK_TIMEOUT_SECONDS/ the code-block timeout ceiling it controls is600(seconds) as an independent literal in multiple places acrosslangwatch/langwatchandlangwatch/langwatch-saas, with no shared source of truth. Nothing enforces that these stay in sync — an operator raising the ceiling in one place silently leaves the others behind, which is exactly the client/server drift bug that langwatch/langwatch#7645 exists to fix for the scenario-client vs nlpgo-server pair. That PR (still open, not merged as of this issue) only closes the drift between two of these sites; the rest are untouched.Where
600(or its absence) lives todayVerified live in the repos, 2026-08-28:
langwatch/services/nlpgo/config.go:114,CodeBlockTimeoutSeconds: 600(also mirrored asopts.DefaultTimeout = 600 * time.Secondinlangwatch/services/nlpgo/app/engine/blocks/codeblock/codeblock.go:115).langwatch-saas/infrastructure/langwatch_nlp_k8s.tf:113-114,NLPGO_ENGINE_CODE_BLOCK_TIMEOUT_SECONDS = "600".langwatch-saas/infrastructure/langwatch_nlp_lambda.tf:265, same literal.langwatch-saas/infrastructure/runtime/modules/langwatch-nlp-lambda/main.tf:276, same literal again (a third, separately-maintained Terraform copy).langwatch-saas/infrastructure/langwatch_workers.tf(added in https://github.com/langwatch/langwatch-saas/pull/1185), same literal, so the scenario-client process actually gets the var forwarded to it — a 4th copy.langwatch/platform/app/src/optimization_studio/server/lambda/index.ts(createLambdaFunction'sEnvironment.Variablesblock, ~line 259) does not setNLPGO_ENGINE_CODE_BLOCK_TIMEOUT_SECONDSat all — these dynamically-created per-project Lambdas silently fall back to whatever in-code default nlpgo/the scenario client ship with, with zero visibility into what that resolves to per-project.langwatch/charts/langwatch/templates/langwatch_nlp/deployment.yamlandlangwatch/charts/langwatch/values.yamlalso never set this var, so a self-hosted install relies entirely on the same in-code default as Make add row/view row/edit role a drawer instead of modal #6, with the same blind spot.platform/app/src/server/nlpgo/timeouts.ts: readsNLPGO_ENGINE_CODE_BLOCK_TIMEOUT_SECONDSwith an in-code fallback of600if unset. Once merged this becomes a fifth independent600literal (a fallback default, not a Terraform value) that must track the Go engine's.Why this matters
None of sites 1-5 (and the future site 8) derive from a shared constant — each is a hand-copied literal. Sites 6 and 7 don't set the var at all, so they rely on the literals in 1/8 staying correct by convention. Raising the ceiling requires a human to remember to touch every one of these; missing one reintroduces exactly the "server raised, client still capped" drift that PR #7645 was written to eliminate — just at a different client (a per-project Lambda, or a self-hosted install) instead of the SaaS workers process.
Suggested fix
Introduce one shared source for the value:
local.nlpgo_code_block_timeout_seconds(or equivalent) inlangwatch-saas/infrastructure, referenced by all 4 Terraform sites (k8s, SaaS lambda, per-project lambda module, workers) instead of the repeated string literal.code-agent.adapter.ts/timeouts.ts(once #7645 lands) import it rather than hardcoding a matching fallback.lambda/index.ts) and the Helm chart, rather than leaving them on implicit in-code defaults.Context
Deferred out of scope from https://github.com/langwatch/langwatch-saas/pull/1185, which added site #5 above (the one new env var that PR needed) but explicitly did not attempt to de-duplicate the pre-existing literal, since that touches files outside what was asked there.