bug: generator emits invalid env var name FORGE_BOT_USER_<service>^^ when service name contains hyphen #852
Labels
No labels
action
backlog
blocked
bug-report
cannot-reproduce
in-progress
in-triage
needs-triage
prediction/actioned
prediction/dismissed
prediction/unreviewed
priority
rejected
reproduced
tech-debt
underspecified
vision
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: disinto-admin/disinto#852
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
A hyphen in an
[agents.X]TOML section name produces invalid shell identifiers in two places — one silently drops the env var, the other crashes the container.Call site 1:
lib/generators.sh(silent drop)For section
[agents.dev-qwen2]this emitsFORGE_BOT_USER_DEV-QWEN2— invalid shell identifier. Docker Compose silently drops it; the container never sees the var.Call site 2:
lib/load-project.sh(crashes dev-poll)_AGENT_VARSis Python-generated and usesf"AGENT_{name.upper()}_BASE_URL={...}"fromtomllib— so a section[agents.dev-qwen2]producesAGENT_DEV-QWEN2_BASE_URL=.... Bash rejects theexportwithnot a valid identifier. Because entrypoint runs underset -euo pipefail, the non-zero return propagates up,wait "${FAST_PIDS[@]}"fails, entrypoint exits, and the container enters a crash-loop (iteration 1 → exit → restart → iteration 1 → ...).Confirmed today on
disinto-agents-llamaafter[agents.dev-qwen2]landed in the project TOML — container restarted every ~3 seconds for several minutes; commenting out the block restored stability.Severity
Not cosmetic — a single hired agent with a hyphen in its section name can take down every other TOML-driven sidecar that shares the
projects/*.toml.dev-qwen2breakingdev-qwentoday is exactly that.Repro
disinto hire-an-agent dev-qwen2 dev --local-model <url> --model <name>(TOML block added:[agents.dev-qwen2]).grep FORGE_BOT_USER_ /home/johba/disinto/docker-compose.yml→ observeFORGE_BOT_USER_DEV-QWEN2(invalid identifier).docker exec disinto-agents-dev-qwen2 env | grep FORGE_BOT_USER→ empty.projects/disinto.toml(e.g.disinto-agents-llamawith #855 fix applied),docker logsshows: followed by container exit and restart.Fix
Normalize the section name the same way in both emitters. The canonical rule (already used for
FORGE_TOKEN_<USER>derivation, see #847):Apply at:
lib/generators.sh—_generate_local_model_services, replace${service_name^^}with${safe_upper}where it flows into env var names (FORGE_BOT_USER_*, any otherFORGE_*_<NAME>keys).lib/load-project.sh— the Python block generatingAGENT_<NAME>_*lines: replacename.upper()withname.upper().replace("-", "_")so the emitted keys are always valid shell identifiers.Secondary (defensive): the
exportloop inload-project.shshould tolerate or pre-validate invalid identifiers rather than letting them tankset -e. Even after fixing the emission, a hand-edited TOML could reintroduce the issue; fail gracefully with a warning instead of crashing.Acceptance
[agents.dev-qwen2]produces env keyFORGE_BOT_USER_DEV_QWEN2(underscore) in generated compose.load-project.shon the same TOML emitsAGENT_DEV_QWEN2_BASE_URL=...(underscore);exportsucceeds.not a valid identifiererrors indocker logs disinto-agents-*for any hired agent with hyphens.llama) unchanged.Affected files
lib/generators.sh—_generate_local_model_serviceslib/load-project.sh— Python AGENT_* emission + shell export loopContext
Caught while bringing up
dev-qwen2as a second parallel llama dev agent. Originally thought cosmetic (compose drops the bad var), but theload-project.shcall site turns it into a hard crash that tookdev-qwenoffline. See #855 for the adjacent FACTORY_REPO/volume-mount gap that exposed this bug (before #855, the poll loop never ran, so load-project was never called, so the crash stayed hidden).Related: #847 (env-var naming rule origin), #855 (silent-zombie mode that hid this bug).