{"record":{"id":"b764ff44ba0c61fa","repo":"paperclipai/paperclip","slug":"unsupported-paperclip-operation","errorCode":null,"errorMessage":"Unsupported Paperclip operation","messagePattern":"Unsupported Paperclip operation","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts","lineNumber":939,"sourceCode":"        });\n      }\n      this.#emit(\n        \"item.completed\",\n        {\n          kind: \"dynamicToolCall\",\n          item: {\n            type: \"tool_result\",\n            id: call.callId,\n            tool_use_id: call.callId,\n            result: \"Semantic completion accepted.\",\n          },\n        },\n        { turnId, itemId: call.callId },\n      );\n      return { accepted: true };\n    }\n    if (!this.#dynamicToolHandler)\n      throw new Error(\"Unsupported Paperclip operation\");\n    try {\n      const result = await this.#dynamicToolHandler({\n        tool,\n        callId: call.callId,\n        threadId: this.#providerSessionId,\n        turnId,\n        arguments: call.arguments,\n      });\n      this.#emit(\n        \"item.completed\",\n        {\n          kind: \"dynamicToolCall\",\n          item: {\n            type: \"tool_result\",\n            id: call.callId,\n            tool_use_id: call.callId,\n            result,\n          },","sourceCodeStart":921,"sourceCodeEnd":957,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts#L921-L957","documentation":"Thrown by OpenCodeHarnessSession when a tool call arrives that requires dynamic (custom/harness-registered) tool handling but no dynamic tool handler was configured on the session. The driver cannot resolve the call on its own, so it refuses with 'Unsupported Paperclip operation'. This is a programming/configuration error, not a transient failure.","triggerScenarios":"A tool invocation is dispatched to the session while this.#dynamicToolHandler is undefined — i.e. the session was created without registering a dynamic tool handler but the model/turn emits a call for a tool that is not one of the driver's built-in tools.","commonSituations":"Developers spawn an OpenCode server session with default options, then the agent calls a custom tool defined only on the Paperclip side; or a refactor renames/removes the dynamicToolHandler option so it silently defaults to undefined.","solutions":["Register a dynamic tool handler when creating the OpenCodeHarnessSession so incoming custom tool calls can be dispatched.","If custom tools are not intended, restrict the agent's tool list/permissions so the model cannot invoke unregistered tools.","Check the session construction code for a misspelled or dropped option that leaves dynamicToolHandler undefined."],"exampleFix":"// before\nconst session = new OpenCodeHarnessSession({ runtime, workspace });\n\n// after\nconst session = new OpenCodeHarnessSession({\n  runtime,\n  workspace,\n  dynamicToolHandler: async ({ tool, callId, threadId, turnId }) => {\n    return dispatchTool(tool, callId, threadId, turnId);\n  },\n});","handlingStrategy":"try-catch","validationCode":"if (session.getDynamicToolHandler?.() == null && toolsMayIncludeCustom) {\n  throw new Error(\"Session requires a dynamicToolHandler for custom tools\");\n}","typeGuard":"function hasDynamicToolHandler(s: unknown): s is { dynamicToolHandler: Function } {\n  return typeof s === \"object\" && s !== null && \"dynamicToolHandler\" in s && typeof (s as any).dynamicToolHandler === \"function\";\n}","tryCatchPattern":"try {\n  await session.submit(toolCall);\n} catch (e) {\n  if (e instanceof Error && e.message === \"Unsupported Paperclip operation\") {\n    // rebuild session with dynamicToolHandler registered\n  }\n  throw e;\n}","preventionTips":["Always pass dynamicToolHandler when the agent's tool list includes custom tools","Add a startup assertion that the handler is set for sessions expecting custom tools","Keep session option names centralized in one factory so they cannot be dropped silently"],"tags":["unsupported-operation","dynamic-tools","session-config"],"backgroundTag":"unsupported-operation","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}