conductor-oss/conductor · error · UnsupportedOperationException

Not supported

Error message

Not supported

What it means

Grok.generateEmbeddings() throws unconditionally because the Grok (xAI) provider only implements chat completion via the OpenAI-compatible /v1/chat/completions endpoint. xAI's Grok models do not expose an embeddings API. The AIModel contract is satisfied by throwing UnsupportedOperationException.

Source

Thrown at ai/src/main/java/org/conductoross/conductor/ai/providers/grok/Grok.java:61

    public Grok(GrokAIConfiguration config, OkHttpClient httpClient) {
        this.config = config;
        OpenAIChatCompletionsApi api =
                new OpenAIChatCompletionsApi(
                        httpClient,
                        config.getApiKey(),
                        config.getBaseURL(),
                        "/v1/chat/completions");
        this.chatModel = new OpenAICompatChatModel(api);
    }

    @Override
    public String getModelProvider() {
        return NAME;
    }

    @Override
    public List<Float> generateEmbeddings(EmbeddingGenRequest embeddingGenRequest) {
        throw new UnsupportedOperationException("Not supported");
    }

    @Override
    public ChatOptions getChatOptions(ChatCompletion input) {
        List<ToolCallback> toolCallbacks = getToolCallback(input);
        Set<String> toolNames =
                toolCallbacks.stream()
                        .map(tc -> tc.getToolDefinition().name())
                        .collect(Collectors.toSet());

        return ToolCallingChatOptions.builder()
                .model(input.getModel())
                .temperature(input.getTemperature())
                .topP(input.getTopP())
                .maxTokens(input.getMaxTokens())
                .stopSequences(input.getStopWords())
                .frequencyPenalty(input.getFrequencyPenalty())
                .presencePenalty(input.getPresencePenalty())

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Route embedding requests to a provider that supports them: 'openai', 'azure_openai', 'cohere', 'bedrock' (Cohere models only), or 'vertex_ai'/'google_gemini'.
  2. Add a capability check before calling generateEmbeddings() — verify the provider name supports embeddings.
  3. If building a generic embedding dispatcher, maintain a whitelist of embedding-capable providers.

Example fix

// before
String provider = "Grok";
List<Float> emb = registry.get(provider)
    .generateEmbeddings(req); // throws

// after
private static final Set<String> EMBEDDING_PROVIDERS =
    Set.of("openai", "azure_openai", "cohere", "bedrock", "vertex_ai", "google_gemini");
if (!EMBEDDING_PROVIDERS.contains(provider)) {
    throw new IllegalArgumentException(
        "Provider " + provider + " does not support embeddings");
}
List<Float> emb = registry.get(provider).generateEmbeddings(req);
Defensive patterns

Strategy: validation

Validate before calling

// Validate Grok supports embeddings before calling
private static final Set<String> EMBEDDING_CAPABLE =
    Set.of("openai", "azure_openai", "cohere", "bedrock", "vertex_ai", "google_gemini");

void validateEmbeddingCapability(String providerName) {
    if (!EMBEDDING_CAPABLE.contains(providerName)) {
        throw new IllegalArgumentException(
            "Provider '" + providerName + "' does not support embeddings. "
            + "Supported: " + EMBEDDING_CAPABLE);
    }
}

Type guard

static boolean supportsEmbeddings(AIModel model) {
    try {
        model.generateEmbeddings(null);
        return true;
    } catch (UnsupportedOperationException e) {
        return false;
    } catch (NullPointerException | IllegalArgumentException e) {
        return true; // passed the unsupported check, failed on null input
    }
}

Try / catch

try {
    return grok.generateEmbeddings(request);
} catch (UnsupportedOperationException e) {
    throw new IllegalArgumentException(
        "Grok does not support embeddings. "
        + "Use openai, cohere, bedrock (cohere.*), or vertex_ai.", e);
}

Prevention

When it happens

Trigger: Calling generateEmbeddings() on a Grok provider instance — e.g. a text-embedding or embedding-generation task routed to provider 'Grok'.

Common situations: Routing an embedding/vector-generation workflow to the Grok provider. Assuming all chat providers also support embeddings. Copying an embedding task config from OpenAI and changing only the provider to Grok.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/6fe944ff78e7cb53. Report an issue: GitHub.