What We Shipped: Geta.Team v2.1.3 + v2.1.4 — Codex Stability, Connectors Access, and Chat UI Cleanup
Two days after v2.1.1 shipped the OpenAI Codex integration, Codex pushed an auto-update. Two days after that, we started getting reports of employees going silent on the first user message. No response, no error in the UI, just a quiet [TERMINAL-EXIT] in the logs two seconds after the message was sent. Nothing in the JSONL rollouts. Nothing obvious in the agent code. It turned out to be one of those bugs where the cause is thirty lines from where you were looking — hiding inside a prompt we didn't write.
v2.1.3 and v2.1.4 shipped on the same day. Between them, seven fixes — most of them quiet-failure bugs that were actively eating user time. Here's the tour.
The Codex EIO bug: why first messages were disappearing
When Codex CLI starts up and detects a newer version on npm, it shows an interactive Update available prompt at the top of the TUI. Three options: Update now / Skip / Skip until next version. The default is option 1.
From the user's point of view, the TUI looked ready. They typed "salut". The "s" went into the update prompt. The Enter that followed selected the default — Update now. Codex spawned npm install -g @openai/codex, exited with Please restart Codex, and our process supervisor recorded a read EIO followed by a clean exit. The chat UI never received a response because the agent had been nuked before it processed a single message.
The fix is two-part. First, /root/.codex/config.toml now starts with check_for_update_on_startup = false, which skips the version check entirely and drops the TUI straight into the chat prompt. Second, a new ensureCodexConfig() runs on server startup (called from both the cluster-worker and standalone server.listen callbacks) and injects that flag into the config file if it's missing. It's idempotent — safe to re-run on every boot — and it uses an ephemeral vibecoder container via the docker socket so we don't need to touch docker-compose.yml or remount anything.
Updates still happen. We just pin the version behind our own deploy cycle instead of letting a spontaneous npm prompt eat user input.
Clear Session now actually clears the session
Second Codex bug, different failure mode. When an employee reset its session, the underlying .jsonl rollout files in /root/.codex/sessions were left on disk. On the next connect_session, vibecoder's findCodexSessionFile picked the most recent rollout without an mtime filter and replayed the prior conversation to the chat UI. Users clicking Clear Session would see their new session start — and then watch it eerily remember everything they'd just cleared.
The delete_session handler in adminProxy.js now destroys the employee container and recursively removes the contents of /app/agents/{user_folder}/{folder_name}/.codex-sessions/. Clean slate, no ghosts.
AGENTS.md sync: Codex and OpenCode can now read the profile
Quick background: Claude reads CLAUDE.md. Codex and OpenCode read AGENTS.md. Our employees are defined by the CLAUDE.md profile in their agent folder — personality, role, available skills, communication preferences. For the Claude-backed employees this just worked. For Codex and OpenCode employees, AGENTS.md was sometimes a one-line redirect to CLAUDE.md (which those tools would ignore), sometimes a full duplicate, and sometimes missing entirely because of a path mix-up that prevented the generation from running.
The path mix-up is worth calling out because it's the kind of bug that hides in plain sight: the code was checking existsSync against hostPath (the path used in docker -v mounts) instead of containerPath (the path inside the getateam container). From inside the container, hostPath always returns false, so the if-branch that generated the file never fired. Switching the check to containerPath made the logic actually run.
The new behavior: on every employee container spawn, AGENTS.md is overwritten with the current contents of CLAUDE.md, prefixed by a warning header explaining that the file is auto-generated and edits will be overwritten on the next session. Both files stay in lockstep. Codex- and OpenCode-backed employees now see the same profile as their Claude peers.
The connector settings 404 that nobody was reporting
This one is almost embarrassing. Four connector frontends — Google, Slack, Teams, Office365 — let users save per-connection settings via fetch. The backend route is POST /api/{connector}/connections/:id/settings. Office365 was using POST. Google, Slack, and Teams were using PUT. The backend only exposes GET and POST on that route, so every Save Settings click in three of the four connectors was silently 404-ing. No error toast, no logged complaint — the modal would close, the user would assume the setting was saved, and nothing would persist.
Three one-word diffs (PUT → POST in GoogleSection.jsx, SlackSection.jsx, TeamsSection.jsx) and that's fixed. The lesson, if there is one: frontend-only 404s are a nastier class of bug than backend errors, because there's no stack trace — just a broken feature that looks like it works.
Non-admin users can now reach the Connectors panel
Sibling bug to the one above. A while back we added a canManageConnectors flag to gate who can see the Connectors sidebar item. The flag is set for admins, workspace owners, and user id 1 — which meant most team members lost access entirely. Connectors are per-user though: every row in google_connections, slack_connections, teams_connections and the rest is keyed by user_id. Each user needs to open the panel to manage their own.
The fix is a one-line gate removal in AppSidebar.jsx. The Connectors item now shows for everyone (still subject to the existing isEE || saasMode enable), and the admin-only sub-sections — SlackBotsSection, TeamsBotSection, TwilioSection — stay hidden behind their existing isOwner checks. The per-user connectors (Slack, Teams, Google, Office365) already render a "not configured by the administrator" state when the user doesn't have ownership plus an unconfigured connector, so nothing leaks. WhatsApp, Telegram, and Discord are user-scannable and stay always-visible.
Net effect: every user can now wire their own Gmail, Slack, Teams, Office365, WhatsApp, Telegram, and Discord accounts to their employees without asking an admin.
The Radix warning storm on every sheet open
If you've been watching the browser console while using the app, you've probably noticed React warnings spraying out every time you opened an employee sheet — Dialog is changing from controlled to uncontrolled, showing up once per sheet, on every open. Not a crash, but not great.
The cause was dumber than it looked. employeeSheet state in Chat.jsx is initialized with 12 keys, including phone and tags. Five reset call sites only passed 10 keys — the last two were missing. After any reset, employeeSheet.phone and employeeSheet.tags were undefined, which made the corresponding <Sheet open={…}> props uncontrolled. The next time a user opened one of those sheets, the prop flipped from undefined to true, and Radix noticed.
Five reset sites updated to include the full 12-key object, plus one strict-boolean coerce on the image preview Sheet (open={!!(showImagePreview && employee && employee.folder_name)} instead of relying on JavaScript's truthy evaluation returning a string). Warnings gone.
Accessibility warnings on 11 settings sheets
Same general shape of bug, different library rule. Radix Dialog and Sheet require an accessible title and recommend a description — otherwise screen readers can't announce the content properly, and React dev mode warns on every open. Eleven of our chat settings sheets (TTS, AI Provider, Tools, Memory Reminder, Webhooks, Contacts, CLAUDE.md, Humanizer, Appearance, Voices, Twilio Voice) rendered custom header markup but skipped Radix's <SheetTitle> and <SheetDescription> primitives.
Each sheet now has an sr-only SheetHeader with the title and description immediately inside <SheetContent> — invisible to sighted users, announced to screen readers. The visible header markup is untouched. Same pattern as the mobile sidebar. The warnings are gone and the sheets are actually accessible now, which matters more than the warnings did.
Nothing in these releases changes what an AI employee can do. They change what they don't silently lose, hide, or warn about on the way there.
Want to test the most advanced AI employees? Try it here: https://Geta.Team