Skip to content

Commit d1e9490

Browse files
committed
fix: enforce strict config validation
1 parent a9fc2ca commit d1e9490

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1028
-824
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ Docs: https://docs.clawd.bot
44

55
## 2026.1.19-1
66

7+
### Breaking
8+
- **BREAKING:** Reject invalid/unknown config entries and refuse to start the gateway for safety; run `clawdbot doctor --fix` to repair.
9+
710
### Changes
811
- Usage: add `/usage cost` summaries and macOS menu cost submenu with daily charting.
912

docs/gateway/configuration.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@ If the file is missing, Clawdbot uses safe-ish defaults (embedded Pi agent + per
1717

1818
> **New to configuration?** Check out the [Configuration Examples](/gateway/configuration-examples) guide for complete examples with detailed explanations!
1919
20+
## Strict config validation
21+
22+
Clawdbot only accepts configurations that fully match the schema.
23+
Unknown keys, malformed types, or invalid values cause the Gateway to **refuse to start** for safety.
24+
25+
When validation fails:
26+
- The Gateway does not boot.
27+
- Only diagnostic commands are allowed (for example: `clawdbot doctor`, `clawdbot logs`, `clawdbot health`, `clawdbot status`, `clawdbot service`, `clawdbot help`).
28+
- Run `clawdbot doctor` to see the exact issues.
29+
- Run `clawdbot doctor --fix` (or `--yes`) to apply migrations/repairs.
30+
31+
Doctor never writes changes unless you explicitly opt into `--fix`/`--yes`.
32+
2033
## Schema + UI hints
2134

2235
The Gateway exposes a JSON Schema representation of the config via `config.schema` for UI editors.

docs/gateway/troubleshooting.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,22 @@ Clawdbot keeps conversation history in memory.
326326

327327
## Common troubleshooting
328328

329+
### “Gateway won’t start — configuration invalid”
330+
331+
Clawdbot now refuses to start when the config contains unknown keys, malformed values, or invalid types.
332+
This is intentional for safety.
333+
334+
Fix it with Doctor:
335+
```bash
336+
clawdbot doctor
337+
clawdbot doctor --fix
338+
```
339+
340+
Notes:
341+
- `clawdbot doctor` reports every invalid entry.
342+
- `clawdbot doctor --fix` applies migrations/repairs and rewrites the config.
343+
- Diagnostic commands like `clawdbot logs`, `clawdbot health`, `clawdbot status`, and `clawdbot service` still run even if the config is invalid.
344+
329345
### “All models failed” — what should I check first?
330346

331347
- **Credentials** present for the provider(s) being tried (auth profiles + env vars).

extensions/bluebubbles/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk";
2+
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
23

34
import { bluebubblesPlugin } from "./src/channel.js";
45
import { handleBlueBubblesWebhookRequest } from "./src/monitor.js";
@@ -8,6 +9,7 @@ const plugin = {
89
id: "bluebubbles",
910
name: "BlueBubbles",
1011
description: "BlueBubbles channel plugin (macOS app)",
12+
configSchema: emptyPluginConfigSchema(),
1113
register(api: ClawdbotPluginApi) {
1214
setBlueBubblesRuntime(api.runtime);
1315
api.registerChannel({ plugin: bluebubblesPlugin });

extensions/copilot-proxy/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
2+
13
const DEFAULT_BASE_URL = "http://localhost:3000/v1";
24
const DEFAULT_API_KEY = "n/a";
35
const DEFAULT_CONTEXT_WINDOW = 128_000;
@@ -61,6 +63,7 @@ const copilotProxyPlugin = {
6163
id: "copilot-proxy",
6264
name: "Copilot Proxy",
6365
description: "Local Copilot Proxy (VS Code LM) provider plugin",
66+
configSchema: emptyPluginConfigSchema(),
6467
register(api) {
6568
api.registerProvider({
6669
id: "copilot-proxy",

extensions/discord/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk";
2+
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
23

34
import { discordPlugin } from "./src/channel.js";
45
import { setDiscordRuntime } from "./src/runtime.js";
@@ -7,6 +8,7 @@ const plugin = {
78
id: "discord",
89
name: "Discord",
910
description: "Discord channel plugin",
11+
configSchema: emptyPluginConfigSchema(),
1012
register(api: ClawdbotPluginApi) {
1113
setDiscordRuntime(api.runtime);
1214
api.registerChannel({ plugin: discordPlugin });

extensions/google-antigravity-auth/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createHash, randomBytes } from "node:crypto";
22
import { readFileSync } from "node:fs";
33
import { createServer } from "node:http";
4+
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
45

56
// OAuth constants - decoded from pi-ai's base64 encoded values to stay in sync
67
const decode = (s: string) => Buffer.from(s, "base64").toString();
@@ -360,6 +361,7 @@ const antigravityPlugin = {
360361
id: "google-antigravity-auth",
361362
name: "Google Antigravity Auth",
362363
description: "OAuth flow for Google Antigravity (Cloud Code Assist)",
364+
configSchema: emptyPluginConfigSchema(),
363365
register(api) {
364366
api.registerProvider({
365367
id: "google-antigravity",

extensions/google-gemini-cli-auth/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
2+
13
import { loginGeminiCliOAuth } from "./oauth.js";
24

35
const PROVIDER_ID = "google-gemini-cli";
@@ -14,6 +16,7 @@ const geminiCliPlugin = {
1416
id: "google-gemini-cli-auth",
1517
name: "Google Gemini CLI Auth",
1618
description: "OAuth flow for Gemini CLI (Google Code Assist)",
19+
configSchema: emptyPluginConfigSchema(),
1720
register(api) {
1821
api.registerProvider({
1922
id: PROVIDER_ID,

extensions/imessage/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk";
2+
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
23

34
import { imessagePlugin } from "./src/channel.js";
45
import { setIMessageRuntime } from "./src/runtime.js";
@@ -7,6 +8,7 @@ const plugin = {
78
id: "imessage",
89
name: "iMessage",
910
description: "iMessage channel plugin",
11+
configSchema: emptyPluginConfigSchema(),
1012
register(api: ClawdbotPluginApi) {
1113
setIMessageRuntime(api.runtime);
1214
api.registerChannel({ plugin: imessagePlugin });

extensions/matrix/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk";
2+
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
23

34
import { matrixPlugin } from "./src/channel.js";
45
import { setMatrixRuntime } from "./src/runtime.js";
@@ -7,6 +8,7 @@ const plugin = {
78
id: "matrix",
89
name: "Matrix",
910
description: "Matrix channel plugin (matrix-js-sdk)",
11+
configSchema: emptyPluginConfigSchema(),
1012
register(api: ClawdbotPluginApi) {
1113
setMatrixRuntime(api.runtime);
1214
api.registerChannel({ plugin: matrixPlugin });

0 commit comments

Comments
 (0)