paperclipai/paperclip · error · WatchdogDecisionApplicationError

evaluation_issue_not_found

evaluation_issue_not_found

Error message

Evaluation issue not found

What it means

When input.evaluationIssueId is supplied, createRecordWatchdogDecision fetches it company-scoped via findEvaluationIssueById; if the ID was provided but no issue is found, it throws WatchdogDecisionApplicationError with code evaluation_issue_not_found. This guards against recording decisions referencing evaluation issues that don't exist or belong to another company.

Source

Thrown at server/src/modules/active-run-watchdog/application/use-cases.ts:143

  evaluationIssueId?: string | null;
  reason?: string | null;
  snoozedUntil?: Date | null;
  createdByRunId?: string | null;
  now?: Date;
};

export function createRecordWatchdogDecision(deps: RecordWatchdogDecisionDeps) {
  return async function recordWatchdogDecision(
    input: RecordWatchdogDecisionUseCaseInput,
  ): Promise<WatchdogDecisionRecord> {
    const run = await deps.reader.findRunForCompany(input.companyId, input.runId);
    if (!run) throw new WatchdogDecisionApplicationError("run_not_found", "Heartbeat run not found");

    const evaluationIssue = input.evaluationIssueId
      ? await deps.reader.findEvaluationIssueById(input.companyId, input.evaluationIssueId)
      : null;
    if (input.evaluationIssueId && !evaluationIssue) {
      throw new WatchdogDecisionApplicationError("evaluation_issue_not_found", "Evaluation issue not found");
    }
    if (input.actor.type === "agent" && !evaluationIssue) {
      throw new WatchdogDecisionApplicationError(
        "evaluation_issue_required",
        "Agent watchdog decisions require the target evaluation issue",
      );
    }

    const boardActor = input.actor.type === "board";
    const assignedRecoveryOwner =
      input.actor.type === "agent" &&
      Boolean(input.actor.agentId) &&
      evaluationIssue !== null &&
      evaluationIssue.originKind === STALE_ACTIVE_RUN_EVALUATION_ORIGIN_KIND &&
      evaluationIssue.originId === run.id &&
      evaluationIssue.hiddenAt === null &&
      !["done", "cancelled"].includes(evaluationIssue.status) &&
      evaluationIssue.assigneeAgentId === input.actor.agentId;

View on GitHub (pinned to 01ad858492)

Solutions

  1. Verify the evaluation issue ID exists and belongs to the same company via the issues API or DB query
  2. Refresh the issue ID from the stale-active-run evaluation issue list before recording the decision
  3. If the ID was optional in your flow, omit evaluationIssueId rather than passing an invalid value (but note agents must supply a valid one)
  4. Check whether the issue was hidden or moved, making the scoped lookup miss it

Example fix

// before
await recordWatchdogDecision({ companyId, runId, evaluationIssueId: staleIssueId, ... });
// after
const issue = await getEvaluationIssue(companyId, issueId);
if (!issue) { throw new Error('evaluation issue missing; refetch from issues list'); }
await recordWatchdogDecision({ companyId, runId, evaluationIssueId: issue.id, ... });
Defensive patterns

Strategy: validation

Validate before calling

const issue = await getEvaluationIssue(companyId, evaluationIssueId); if (!issue) throw new Error(`evaluation issue ${evaluationIssueId} not found in company ${companyId}`);

Type guard

null

Try / catch

try { await recordWatchdogDecision(input); } catch (e) { if (e.code === 'evaluation_issue_not_found') { /* refetch issue from issues list; drop stale payloads */ } else throw e; }

Prevention

When it happens

Trigger: recordWatchdogDecision called with a non-null evaluationIssueId that resolves to no issue within input.companyId — wrong ID, deleted/hidden issue outside query filters, or an ID from a different company.

Common situations: Stale issue IDs cached in a UI after the issue was deleted; copying issue IDs between company environments; typos in IDs from API logs; agent scripts replaying old decision payloads.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/4c8c6abd02923e47. Report an issue: GitHub.