Skip to content

Gateway crashes on non-voice bootstrap when OPENAI_API_KEY is in the environment #70

Description

@kenadams1990

Summary

inkbox-claude bootstrap without --voice-ai produces a gateway that crashes on startup on any machine that has OPENAI_API_KEY exported in the environment (very common — LiteLLM proxies, other AI tooling, shell profiles). The daemon exits and bootstrap/start report Claude Code gateway did not become ready.

Environment

  • inkbox-claude installed via the curl | bash installer, app at ~/.inkbox-claude/app (venv-isolated), Python 3.13, macOS.
  • OPENAI_API_KEY present in the environment the detached daemon inherits (in our case exported by an unrelated LiteLLM rotation proxy in a shell profile). No voice/realtime config in ~/.inkbox-claude/.env.

Steps to reproduce

  1. Have OPENAI_API_KEY exported in the environment.
  2. inkbox-claude bootstrap --identity <handle> --start-gateway without --voice-ai.
  3. Gateway fails to become ready; check ~/.inkbox-claude/gateway.log.

Expected

With no voice flags and no realtime config, the gateway should start with a non-voice/inkbox_tts_stt stack and ignore an unrelated ambient OPENAI_API_KEY.

Actual

  • bootstrap returns {"status":"error","error":"Claude Code gateway did not become ready"}.
  • gateway.log shows: RuntimeError: INKBOX_VOICE_STACK=openai_realtime requires INKBOX_REALTIME_API_KEY raised in gateway.py run().
  • inkbox-claude doctor confusingly reports phone voice stack openai_realtime and OpenAI Realtime key set even though nothing voice-related is configured in .env.

Root cause (from reading the app source)

  • bootstrap only writes INKBOX_REALTIME_ENABLED=false inside _configure_voice(), which is gated behind --voice-ai (bootstrap.py, ~L137 / ~L211). Without --voice-ai, that line is never written.
  • With the flag absent, resolve_voice_stack() in config.py falls through to a heuristic: if any OPENAI_API_KEY is in the environment, assume voice_stack=openai_realtime.
  • _read_realtime_config() then reads INKBOX_REALTIME_API_KEY or OPENAI_API_KEY, so the ambient key satisfies the key check — but realtime.enabled is still False (needs INKBOX_REALTIME_ENABLED=true), so the gateway's startup invariant raises and the daemon exits. doctor sees the same ambient key, hence its misleading output.

Workaround (config only, survives plugin updates)

printf '%s\n' 'INKBOX_REALTIME_ENABLED=false' >> ~/.inkbox-claude/.env
inkbox-claude restart

resolve_voice_stack then returns inkbox_tts_stt before it ever consults OPENAI_API_KEY.

Suggested fix

Don't infer openai_realtime from a bare ambient OPENAI_API_KEY. Gate the realtime stack on an explicit opt-in (INKBOX_REALTIME_ENABLED=true or an Inkbox-specific INKBOX_REALTIME_API_KEY), and/or write INKBOX_REALTIME_ENABLED=false during a non-voice bootstrap so the default install is deterministic regardless of unrelated env vars.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions