paperclipai/paperclip · error · Error

paperclip_runner_file_handoff_workspace_unavailable

paperclip_runner_file_handoff_workspace_unavailable

Error message

paperclip_runner_file_handoff_workspace_unavailable

What it means

Thrown at the start of #registerDeliverable when the run's binding has no workspaceRoot (or it is empty after trim). Registering a deliverable requires a file handoff workspace to persist the artifact, so without a bound workspace the tool refuses immediately with this sentinel error code.

Solutions

  1. Ensure the run is created with a bound workspace so binding.workspaceRoot is populated before calling register_deliverable.
  2. If the run intentionally has no workspace, use a different reporting path (e.g. report_progress with the artifact content) instead of file handoff.
  3. Inspect the native runtime binding construction to confirm workspaceRoot is passed and not cleared by trim/normalization.
Defensive patterns

Strategy: validation

Validate before calling

if (!binding.workspaceRoot?.trim()) {
  throw new Error('register_deliverable requires a workspace-bound run');
}

Type guard

function hasWorkspace(b: { workspaceRoot?: string | null }): b is { workspaceRoot: string } {
  return typeof b.workspaceRoot === 'string' && b.workspaceRoot.trim().length > 0;
}

Prevention

When it happens

Trigger: Calling the register_deliverable runner tool from a run whose binding.workspaceRoot is undefined/empty — e.g. API-driven or remote runs created without a workspace, or adapters that do not clone a repo workspace.

Common situations: Runs launched in headless/no-checkout mode, misconfigured native runtime that omits workspaceRoot in the binding, environments where the workspace was cleaned up before the run reported its deliverable.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/6bb0a1b4edeb27af. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/native-runtime/paperclip-runner-tool-authority.ts:923

        blockedByIssueIds,
        actorAgentId: this.binding.agentId,
      }, tx);
      if (!updated) throw new Error("paperclip_runner_task_not_found");
      return {
        commandId: `set-dependencies:${updated.id}:${updated.statusVersion}`,
        disposition: "applied",
        stateRevision: updated.statusVersion,
        entityRefs: [updated.id, ...blockedByIssueIds],
        scheduledWakeIds: [],
      };
    });
  }

  async #registerDeliverable(input: Record<string, unknown>): Promise<unknown> {
    const idempotencyKey = requiredString(input.idempotencyKey);
    const workspaceRoot = this.binding.workspaceRoot?.trim();
    if (!workspaceRoot) {
      throw new Error("paperclip_runner_file_handoff_workspace_unavailable");
    }
    let publication:
      Awaited<ReturnType<typeof persistActivity>>["publication"] | null = null;
    let rollbackDefinitePreCommitFailure: (() => Promise<void>) | null = null;
    const result = await this.#withMutationReceipt(
      "register_deliverable",
      idempotencyKey,
      input,
      async (tx, context) => {
        const prepared = await prepareNativeRunnerFileHandoff({
          db: tx,
          binding: {
            companyId: this.binding.companyId,
            issueId: this.binding.issueId,
            runId: this.binding.runId,
            agentId: this.binding.agentId,
            workspaceRoot,
            executionTargetKind: this.binding.executionTargetKind ?? "local",

View on GitHub (pinned to 3f1d897a7c)