diff --git a/kiloclaw/controller/src/config-writer.test.ts b/kiloclaw/controller/src/config-writer.test.ts index a91ca6000..d7d33b18a 100644 --- a/kiloclaw/controller/src/config-writer.test.ts +++ b/kiloclaw/controller/src/config-writer.test.ts @@ -251,6 +251,9 @@ describe('generateBaseConfig', () => { expect(config.models.providers.kilocode.headers['X-KiloCode-OrganizationId']).toBe( 'org_abc123' ); + // baseUrl must be a string (OpenClaw schema requires it); fall back to + // the production URL when no KILOCODE_API_BASE_URL override is active. + expect(config.models.providers.kilocode.baseUrl).toBe('https://api.kilo.ai/api/gateway/'); expect(config.models.providers.kilocode.models).toEqual([]); }); diff --git a/kiloclaw/controller/src/config-writer.ts b/kiloclaw/controller/src/config-writer.ts index 5b23bd560..f73041ebe 100644 --- a/kiloclaw/controller/src/config-writer.ts +++ b/kiloclaw/controller/src/config-writer.ts @@ -187,6 +187,10 @@ export function generateBaseConfig( config.models = config.models ?? {}; config.models.providers = config.models.providers ?? {}; config.models.providers.kilocode = config.models.providers.kilocode ?? {}; + // OpenClaw's provider schema requires baseUrl to be a string. Preserve an + // existing dev override (KILOCODE_API_BASE_URL), otherwise use the production URL. + config.models.providers.kilocode.baseUrl = + config.models.providers.kilocode.baseUrl ?? 'https://api.kilo.ai/api/gateway/'; config.models.providers.kilocode.headers = config.models.providers.kilocode.headers ?? {}; config.models.providers.kilocode.headers['X-KiloCode-OrganizationId'] = env.KILOCODE_ORGANIZATION_ID;