{"record":{"id":"410d0fa6bfe8cbf2","repo":"paperclipai/paperclip","slug":"runid-is-required","errorCode":null,"errorMessage":"runId is required","messagePattern":"runId is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugins/plugin-llm-wiki/src/worker.ts","lineNumber":555,"sourceCode":"        maxCharacters: typeof params.maxCharacters === \"number\" ? params.maxCharacters : null,\n        maxCharactersPerSource: typeof params.maxCharactersPerSource === \"number\" ? params.maxCharactersPerSource : null,\n        backfillStartAt: stringField(params.backfillStartAt),\n        backfillEndAt: stringField(params.backfillEndAt),\n        routineRun: params.routineRun === true,\n        includeComments: params.includeComments !== false,\n        includeDocuments: params.includeDocuments !== false,\n        workItemId: stringField(params.workItemId),\n        operationIssueId: stringField(params.operationIssueId),\n      });\n    });\n\n    ctx.actions.register(\"record-paperclip-distillation-outcome\", async (params) => {\n      const status = stringField(params.status);\n      if (status !== \"succeeded\" && status !== \"failed\" && status !== \"review_required\") {\n        throw new Error(\"status must be succeeded, failed, or review_required\");\n      }\n      const runId = stringField(params.runId);\n      if (!runId) throw new Error(\"runId is required\");\n      return recordPaperclipDistillationOutcome(ctx, {\n        companyId: readCompanyIdFromParams(params),\n        wikiId: stringField(params.wikiId),\n        spaceSlug: stringField(params.spaceSlug),\n        runId,\n        cursorId: stringField(params.cursorId),\n        status,\n        sourceHash: stringField(params.sourceHash),\n        sourceWindowEnd: stringField(params.sourceWindowEnd),\n        warning: stringField(params.warning),\n        costCents: typeof params.costCents === \"number\" ? params.costCents : null,\n        retryCount: typeof params.retryCount === \"number\" ? params.retryCount : null,\n      });\n    });\n\n    ctx.actions.register(\"distill-paperclip-project-page\", async (params) => {\n      return distillPaperclipProjectPage(ctx, {\n        companyId: readCompanyIdFromParams(params),","sourceCodeStart":537,"sourceCodeEnd":573,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/plugins/plugin-llm-wiki/src/worker.ts#L537-L573","documentation":"Thrown by the record-paperclip-distillation-outcome worker action after status validation when params.runId is missing or blank. runId is the correlation key for the distillation run; without it the outcome cannot be matched to its cursor/run record.","triggerScenarios":"Calling record-paperclip-distillation-outcome with a valid status but runId absent, empty, or whitespace-only (stringField returns null).","commonSituations":"The run handler forgot to propagate runId; the param was keyed 'run_id' instead of 'runId'; the run was triggered outside the normal queue and never assigned an id.","solutions":["Always pass runId (the run's identifier from when it was queued/started).","Check param key spelling (camelCase runId).","Generate and persist a runId at queue time so it is available at outcome time."],"exampleFix":"// before\nrecord(..., { status: 'succeeded' });\n// after\nrecord(..., { status: 'succeeded', runId });","handlingStrategy":"validation","validationCode":"function assertRunId(value: unknown) {\n  if (typeof value !== 'string' || !value.trim()) throw new Error('runId is required');\n}","typeGuard":"function isNonBlankString(value: unknown): value is string {\n  return typeof value === 'string' && value.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Persist runId at queue time so it is available at outcome time.","Use camelCase param keys (runId)."],"tags":["paperclip","distillation","validation"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}