conductor-oss/conductor · error · RuntimeException

{"error":{errors},"response":{output}}

Error message

{"error":{errors},"response":{output}}

What it means

Thrown in LLMHelper.extractResponse() when JSON output was requested (input.isJsonOutput()) but the LLM returned an empty response list (hasJsonOutput stays false) and there are no tool calls. The exception carries a JSON string with 'error' and 'response' keys detailing what went wrong during JSON extraction.

Source

Thrown at ai/src/main/java/org/conductoross/conductor/ai/LLMHelper.java:280

                        } else {
                            error =
                                    validateJsonSchema(
                                            input.getInputSchema(),
                                            (Map<String, Object>) responseObj);
                        }
                        if (error != null) {
                            errors.add(
                                    String.format(
                                            "Output does not confirm to the schema.  errors: %s",
                                            error));
                        }
                    }
                    output.add(responseObj);
                }
                llmResponse.setResult(output);
                if (input.isJsonOutput() && !hasJsonOutput && !llmResponse.hasToolCalls()) {
                    Map<String, Object> outputErrors = Map.of("error", errors, "response", output);
                    throw new RuntimeException(objectMapper.writeValueAsString(outputErrors));
                }
            }
            default -> llmResponse.setResult(result.toString());
        }
    }

    @SneakyThrows
    private Object tryToConvertToJSON(String responseText, ChatCompletion chatCompletion) {
        try {
            responseText = responseText.trim();
            if (responseText.startsWith("```json")) {
                responseText = responseText.substring("```json".length());
                responseText =
                        responseText.substring(0, responseText.length() - "```".length() - 1);
            }
            Map<String, Object> map = objectMapper.readValue(responseText, MAP_OF_STRING_TO_OBJ);
            if (chatCompletion.getOutputSchema() != null) {
                String error = validateJsonSchema(chatCompletion.getInputSchema(), map);

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Inspect the thrown JSON payload — the 'error' array and 'response' array reveal what the model actually returned
  2. Check the LLM finishReason (e.g. CONTENT_FILTER, MAX_TOKENS) to understand why no text was produced
  3. Increase maxTokens or adjust the prompt to avoid content-filter triggers
  4. Retry the call — empty responses can be transient with some providers
Defensive patterns

Strategy: try-catch

Validate before calling

// Before expecting JSON output, verify the ChatCompletion is properly configured
if (chatCompletion.isJsonOutput()) {
    // Ensure the prompt includes clear JSON formatting instructions
    // and maxTokens is sufficient for the expected output size
}

Try / catch

try {
    LLMResponse response = llmHelper.chatComplete(task, llm, chatCompletion, location, logger);
} catch (RuntimeException e) {
    // The message is a JSON string with 'error' and 'response' keys
    try {
        Map<String, Object> payload = objectMapper.readValue(e.getMessage(), Map.class);
        List<String> errors = (List<String>) payload.get("error");
        List<Object> responses = (List<Object>) payload.get("response");
        log.warn("LLM JSON output failed: errors={}, responses={}", errors, responses);
    } catch (Exception parseEx) {
        log.error("Unexpected error from LLM helper: {}", e.getMessage(), e);
    }
    taskResult.setStatus(TaskResult.Status.FAILED);
    taskResult.setReasonForIncompletion(e.getMessage());
}

Prevention

When it happens

Trigger: The LLM returns a List result that is empty or where no iteration ran, isJsonOutput() is true on the ChatCompletion, and llmResponse.hasToolCalls() is false. This is an edge case where the model produced no usable output when structured JSON was expected.

Common situations: The LLM returned an empty or whitespace-only response. The model hit a content filter or max-token limit and produced no text. The prompt was malformed causing the model to return nothing. A provider API change caused empty results.

Related errors


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