-
Notifications
You must be signed in to change notification settings - Fork 54
droid exec --model rejects all custom model IDs (BYOK) #787
Description
Summary
droid exec --model <custom-model-id> rejects all custom model IDs with "Invalid model" even though they are listed as available in the error output. Only the current session default custom model works via --model. Built-in model IDs route through Factory's API (returning 402 for non-subscribers) instead of the user's BYOK proxy.
Environment
- Droid CLI version: 0.70.0, 0.74.0 (tested both)
- OS: macOS (Darwin 23.6.0, arm64)
- Custom models: Configured in
~/.factory/settings.jsonwith BYOK proxy at localhost
Steps to Reproduce
- Configure custom models in
~/.factory/settings.json(e.g., Gemini Flash via OpenAI-compatible proxy) - Run:
droid exec --auto low --model "custom:Gemini-3-Flash-Low-[Proxy]-18" "Say hello" - Observe: "Invalid model" error, even though "Gemini 3 Flash Low [Proxy]" is listed under "Available custom models"
Tested formats that all fail:
custom:Gemini-3-Flash-Low-[Proxy]-18(theidfield from settings.json)Gemini 3 Flash Low [Proxy](thedisplayNamefrom settings.json)custom:Claude-Haiku-4.5-Medium-Thinking-6(non-default Claude custom model)
The only custom model that works is the one set as sessionDefaultSettings.model — which is effectively a no-op since it's already the default.
Built-in model IDs (e.g., claude-haiku-4-5-20251001) are accepted syntactically but fail with 402 Payment Required because they route through Factory's API instead of the BYOK proxy.
Expected Behavior
--model should accept any custom model ID from ~/.factory/settings.json and route through the configured BYOK endpoint, not just the current session default.
Impact
This blocks headless droid exec workflows that need to select specific models programmatically (e.g., using a cheap model for batch enrichment pipelines while keeping an expensive model as the interactive default).
Workaround
Omit the --model flag entirely and rely on the session default. This means you can't select different models for different use cases without manually changing sessionDefaultSettings.model between runs.
Log Evidence
From ~/.factory/logs/droid-log-single.log:
MetaError: Invalid model: custom:Gemini-3-Flash-Low-[Proxy]-18
at syR (src/commands/assertValidOptions.ts:83:17)
at async <anonymous> (src/commands/exec.ts:957:21)
The validation in assertValidOptions.ts lists custom models but fails to match against them.