paperclipai/paperclip · error

Task-watchdog runs cannot change watchdog configuration.

Error message

Task-watchdog runs cannot change watchdog configuration.

What it means

403 from rejectTaskWatchdogConfigMutation: the mutating request comes from a task-watchdog run context, and watchdog-scoped runs are not allowed to change watchdog configuration itself.

Source

Thrown at server/src/routes/issues.ts:4321

      identifier?: string | null;
    },
    options: { allowVisibleIssueWrite?: boolean } = {},
  ) {
    if (req.actor.type !== "agent") return true;
    const actorAgentId = req.actor.agentId;
    if (!actorAgentId) {
      res.status(403).json({ error: "Agent authentication required" });
      return false;
    }
    // Task-watchdog runs receive a scoped *grant* to mutate issues inside the
    // watched subtree. This must be evaluated before the base assignee-ownership
    // boundary below: that boundary denies an agent mutating an issue owned by a
    // different agent, which is exactly the watchdog's primary job
    // (SPEC-implementation §9.9 — comment, transition, reassign within the
    // watched subtree). The watchdog scope can only widen access to the watched
    // subtree; downstream status-transition, assignment, recovery, and budget
    // guards in the route handlers still apply.
    const watchdogScope = await resolveTaskWatchdogMutationScope(db, req.actor);
    if (watchdogScope.kind !== "none") {
      const scopeResult = await taskWatchdogScopeAllowsIssueMutation(db, watchdogScope, issue);
      if (scopeResult.kind === "invalid") {
        res.status(403).json({
          error: scopeResult.detail,
          details: {
            issueId: issue.id,
            securityPrinciples: ["Least Privilege", "Complete Mediation", "Fail Securely"],
          },
        });
        return false;
      }
      return assertFreshTaskWatchdogSourceMutation(res, watchdogScope, issue);
    }
    const boundaryDecision = await decideIssueAccess(req, issue, "issue:mutate");
    if (!boundaryDecision.allowed) {
      return denyIssueWrite(req, res, issue, issueWriteDenialCodeForDecision(boundaryDecision));
    }

View on GitHub (pinned to 01ad858492)

Solutions

  1. This is an authorization rule, not a bug: perform the action with an actor that satisfies the stated constraint (board user, the owning agent, or an in-scope resource).
  2. If access should be allowed, verify the actor's credentials/company scope and the resource's ownership before retrying.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at server/src/routes/issues.ts:4157 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18). Data as JSON: /api/errors/a4630956a05e6ae8. Report an issue: GitHub.