openclaw - 💡(How to fix) Fix [Bug]: Kilo provider payload rejection on chat completions (expected array, received string)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

When running cron tasks or nested subagents calling deepseek-v4-flash via the kilo provider, the LLM request fails with:

embedded run agent end: runId=... error=LLM request failed: provider rejected the request schema or tool payload. rawError=400 Invalid input: expected array, received string

Error Message

embedded run agent end: runId=... error=LLM request failed: provider rejected the request schema or tool payload. rawError=400 Invalid input: expected array, received string The Kilo.ai Gateway and deepseek validation schemas are strictly configured to accept only a JSON array for the stop parameter. When OpenClaw serializes the payload passing a raw string for stop, the provider's API rejects the entire payload with a 400 Bad Request validation error.

Root Cause

In standard OpenAI-compatible API specifications, the stop parameter (representing stop sequences) can be parsed either as a single string (e.g. "stop": "\n") or a JSON array of strings (e.g. "stop": ["\n"]).

The Kilo.ai Gateway and deepseek validation schemas are strictly configured to accept only a JSON array for the stop parameter. When OpenClaw serializes the payload passing a raw string for stop, the provider's API rejects the entire payload with a 400 Bad Request validation error.

Fix Action

Fix / Workaround

function createKilocodeWrapper(baseStreamFn, thinkingLevel) {
    // ...
    return streamWithPayloadPatch(underlying, model, context, {
        ...options,
        headers
    }, (payload) => {
        normalizeProxyReasoningPayload(payload, thinkingLevel);
    });
}

Proposed Fix

We can safely normalize payload.stop within the payload patch function inside createKilocodeWrapper to convert a single string into a single-element array, keeping it fully compliant with Kilo's strict validation schema:

function createKilocodeWrapper(baseStreamFn, thinkingLevel) {
    // ...
    return streamWithPayloadPatch(underlying, model, context, {
        ...options,
        headers
    }, (payload) => {
        normalizeProxyReasoningPayload(payload, thinkingLevel);
        if (payload && typeof payload === "object" && typeof payload.stop === "string") {
            payload.stop = [payload.stop];
        }
    });
}

Code Example

embedded run agent end: runId=... error=LLM request failed: provider rejected the request schema or tool payload. rawError=400 Invalid input: expected array, received string

---

function createKilocodeWrapper(baseStreamFn, thinkingLevel) {
    // ...
    return streamWithPayloadPatch(underlying, model, context, {
        ...options,
        headers
    }, (payload) => {
        normalizeProxyReasoningPayload(payload, thinkingLevel);
    });
}

---

function createKilocodeWrapper(baseStreamFn, thinkingLevel) {
    // ...
    return streamWithPayloadPatch(underlying, model, context, {
        ...options,
        headers
    }, (payload) => {
        normalizeProxyReasoningPayload(payload, thinkingLevel);
        if (payload && typeof payload === "object" && typeof payload.stop === "string") {
            payload.stop = [payload.stop];
        }
    });
}
RAW_BUFFERClick to expand / collapse

Description

When running cron tasks or nested subagents calling deepseek-v4-flash via the kilo provider, the LLM request fails with:

embedded run agent end: runId=... error=LLM request failed: provider rejected the request schema or tool payload. rawError=400 Invalid input: expected array, received string

Cause

In standard OpenAI-compatible API specifications, the stop parameter (representing stop sequences) can be parsed either as a single string (e.g. "stop": "\n") or a JSON array of strings (e.g. "stop": ["\n"]).

The Kilo.ai Gateway and deepseek validation schemas are strictly configured to accept only a JSON array for the stop parameter. When OpenClaw serializes the payload passing a raw string for stop, the provider's API rejects the entire payload with a 400 Bad Request validation error.

Location of the Issue

The payload transformation for the Kilocode/Kilo provider is handled by createKilocodeWrapper in src/plugin-sdk/src/plugin-sdk/provider-stream.ts (compiled to /dist/proxy-stream-wrappers-B-pawBvX.js):

function createKilocodeWrapper(baseStreamFn, thinkingLevel) {
    // ...
    return streamWithPayloadPatch(underlying, model, context, {
        ...options,
        headers
    }, (payload) => {
        normalizeProxyReasoningPayload(payload, thinkingLevel);
    });
}

Proposed Fix

We can safely normalize payload.stop within the payload patch function inside createKilocodeWrapper to convert a single string into a single-element array, keeping it fully compliant with Kilo's strict validation schema:

function createKilocodeWrapper(baseStreamFn, thinkingLevel) {
    // ...
    return streamWithPayloadPatch(underlying, model, context, {
        ...options,
        headers
    }, (payload) => {
        normalizeProxyReasoningPayload(payload, thinkingLevel);
        if (payload && typeof payload === "object" && typeof payload.stop === "string") {
            payload.stop = [payload.stop];
        }
    });
}

This preserves expected behavior for downstream callers while ensuring robust compatibility with Kilo's API endpoint.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Bug]: Kilo provider payload rejection on chat completions (expected array, received string)