paperclipai/paperclip · error
Job not found
Error message
Job not found
What it means
Returned as HTTP 404 by GET /api/plugins/:pluginId/jobs/:jobId/runs when the plugin exists but jobDeps.jobStore.getJobByIdForPlugin(plugin.id, jobId) finds no job — either the jobId is wrong or the job belongs to a different plugin. The plugin+job pair must both match.
Source
Thrown at server/src/routes/plugins.ts:2603
* Errors: 404 if plugin not found
*/
router.get("/plugins/:pluginId/jobs/:jobId/runs", async (req, res) => {
assertBoardOrgAccess(req);
if (!jobDeps) {
res.status(501).json({ error: "Job scheduling is not enabled" });
return;
}
const { pluginId, jobId } = req.params;
const plugin = await resolvePlugin(registry, pluginId);
if (!plugin) {
res.status(404).json({ error: "Plugin not found" });
return;
}
const job = await jobDeps.jobStore.getJobByIdForPlugin(plugin.id, jobId);
if (!job) {
res.status(404).json({ error: "Job not found" });
return;
}
const limit = req.query.limit ? parseInt(req.query.limit as string, 10) : 25;
if (isNaN(limit) || limit < 1 || limit > 500) {
res.status(400).json({ error: "limit must be a number between 1 and 500" });
return;
}
try {
const runs = await jobDeps.jobStore.listRunsByJob(jobId, limit);
res.json(runs);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
res.status(500).json({ error: message });
}
});
View on GitHub (pinned to a7e689b3c3)
Solutions
- List the plugin's jobs with GET /api/plugins/:pluginId/jobs and copy the exact jobId
- Confirm the jobId belongs to the plugin in the URL path, not just to the instance
- If the job was deleted, re-create it (or the plugin's install flow) before querying runs
Example fix
// before GET /api/plugins/scheduler/jobs/job-from-notifier-plugin/runs // after GET /api/plugins/scheduler/jobs/8a2f.../runs // id returned by /jobs list
Defensive patterns
Strategy: validation
Validate before calling
const jobs = await (await fetch(`/api/plugins/${pluginId}/jobs`)).json();
if (!jobs.some(j => j.id === jobId)) throw new Error(`Job ${jobId} not found for plugin ${pluginId}`); Try / catch
try { await listJobRuns(pluginId, jobId, limit); } catch (e) { if (e.status === 404 && /Job not found/.test(e.body.error)) refreshJobList(pluginId); else throw e; } Prevention
- Always fetch job ids from the plugin's own /jobs listing
- Trim whitespace from copied ids; never hand-edit UUIDs
- After plugin reinstall, re-resolve job ids before showing run history
When it happens
Trigger: Using a jobId from another plugin, a deleted/expired job, or a copy-paste id with a typo or extra whitespace.
Common situations: Cross-plugin id confusion in scripts; UI state referencing a job deleted by a plugin reinstall; truncated UUIDs in logs.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Plugin does not declare a UI bundle
- Plugin UI directory not found
- File not found
- Invalid status '${rawStatus}'. Must be one of: ${validStatus
- ${name} must be a JSON object
AI-assisted analysis of paperclipai/paperclip@a7e689b3c3 (2026-08-18).
Data as JSON: /api/errors/fe17b5ee6f8253c7.
Report an issue: GitHub.