Skip to content

POST /api/plugins/skills accepts a non-string slug/summary and answers 500 instead of 400 #494

Description

@Ayush7614

What

POST /api/plugins/skills in server/src/plugins/routes.ts:568-588 checks presence with !body?.slug and then runs /.../.test(body.slug).

RegExp.test coerces, so {"slug":123,...} tests the string "123" and passes validation. summary has no type check at all (body.summary ?? ""), so {"summary":{}} reaches store.installSkill and the Drizzle/PG insert throws an uncaught error — a 500 for a caller error.

Siblings on the same router (POST /grants, POST /call) already require typeof === "string" + .trim() and answer 400.

Repro

  1. POST /api/plugins/skills with {"slug":123,"title":"t","instructions":"i"} → passes validation, 500 from the store insert.
  2. POST /api/plugins/skills with {"slug":"ok-slug","title":"t","instructions":"i","summary":{}} → passes validation, 500 from the store insert.

Expected: 400 naming the field, no DB write, matching the grants/call routes.

Where it runs

Stateless request validation in the server process. Same 400 on every replica; no shared state, no fan-out, no new listener/schedule.

Fix sketch

Require typeof slug === "string" before the regex, require summary === undefined || typeof summary === "string" (and trim title/instructions already imply strings), return 400 otherwise with the existing message shape. Add route tests covering numeric slug and object/array summary.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions