paperclipai/paperclip · error
Invalid status '${rawStatus}'. Must be one of: ${validStatus
Error message
Invalid status '${rawStatus}'. Must be one of: ${validStatuses.join(", ")} What it means
Returned as HTTP 400 by GET /api/plugins/:pluginId/jobs when the optional ?status= query filter is present but not one of the allowed values active, paused, failed. The message lists the accepted values verbatim.
Source
Thrown at server/src/routes/plugins.ts:2558
*/
router.get("/plugins/:pluginId/jobs", async (req, res) => {
assertBoardOrgAccess(req);
if (!jobDeps) {
res.status(501).json({ error: "Job scheduling is not enabled" });
return;
}
const { pluginId } = req.params;
const plugin = await resolvePlugin(registry, pluginId);
if (!plugin) {
res.status(404).json({ error: "Plugin not found" });
return;
}
const rawStatus = req.query.status as string | undefined;
const validStatuses = ["active", "paused", "failed"];
if (rawStatus !== undefined && !validStatuses.includes(rawStatus)) {
res.status(400).json({
error: `Invalid status '${rawStatus}'. Must be one of: ${validStatuses.join(", ")}`,
});
return;
}
try {
const jobs = await jobDeps.jobStore.listJobs(
plugin.id,
rawStatus as "active" | "paused" | "failed" | undefined,
);
res.json(jobs);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
res.status(500).json({ error: message });
}
});
/**View on GitHub (pinned to a7e689b3c3)
Solutions
- Use exactly one of: active, paused, failed
- Omit ?status entirely to list all jobs
- Fix the client-side enum that feeds the filter to the three supported values
Example fix
// before GET /api/plugins/scheduler/jobs?status=running // after GET /api/plugins/scheduler/jobs?status=active
Defensive patterns
Strategy: validation
Validate before calling
const JOB_STATUSES = ['active', 'paused', 'failed'] as const;
type JobStatus = typeof JOB_STATUSES[number];
function isJobStatus(v: string): v is JobStatus { return (JOB_STATUSES as readonly string[]).includes(v); }
if (status !== undefined && !isJobStatus(status)) throw new Error(`status must be one of: ${JOB_STATUSES.join(', ')}`); Type guard
const JOB_STATUSES = ['active', 'paused', 'failed'] as const;
type JobStatus = typeof JOB_STATUSES[number];
function isJobStatus(v: string): v is JobStatus {
return (JOB_STATUSES as readonly string[]).includes(v);
} Try / catch
try { await listPluginJobs(pluginId, status); } catch (e) { if (e.status === 400 && /Invalid status/.test(e.body.error)) fallbackToAllJobs(); else throw e; } Prevention
- Drive filter dropdowns from a shared constant matching the API enum
- Never invent status values from run-state vocabulary
- Omit the filter rather than guessing when unsure
When it happens
Trigger: Passing ?status=running, ?status=succeeded, ?status=completed, or any free-text value; passing multiple comma-joined statuses like active,paused.
Common situations: Assuming job statuses mirror run statuses (e.g. 'succeeded'); copying status vocabulary from another API; UI dropdown fed from the wrong enum source.
Related errors
- Invalid status '${String(rawStatus)}'. Must be one of: ${PLU
- limit must be a number between 1 and 500
- Invalid file path
- devUiUrl must use http or https protocol
- devUiUrl must target localhost
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-18).
Data as JSON: /api/errors/8b560400102e56b0.
Report an issue: GitHub.