{"record":{"id":"00f32c54a8ea335e","repo":"deepseek-ai/deepseek-harness","slug":"tool-execution-arguments-must-be-losslessly-json-s","errorCode":null,"errorMessage":"tool execution arguments must be losslessly JSON-serializable","messagePattern":"tool execution arguments must be losslessly JSON-serializable","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/tools/src/index.ts","lineNumber":1414,"sourceCode":"      },\n    }\n    // Capture the finalizer BEFORE argument materialization: the\n    // `finalizeContent` contract snapshots the callback when the call starts,\n    // and an arguments getter can replace or clear the registered callback\n    // during `snapshotJsonValue`. The collapse only decides whether the\n    // CAPTURED callback is retained: the pre-dispatch abort path keeps it\n    // (the cancellation contract routes aborted results through it — a getter\n    // that aborts mid-materialization before an invalid-args failure lands in\n    // the same retained path), while the `UNKNOWN_TOOL` denial and the\n    // invalid-args failure of a NON-ABORTED collapsed call drop it (the call\n    // could never execute).\n    const capturedFinalizer = visible?.finalizeContent?.bind(visible)\n    const finalizerFor = (): ToolDefinition['finalizeContent'] | undefined =>\n      collapsed && !signal.aborted ? undefined : capturedFinalizer\n    try {\n      const detached = snapshotJsonValue(exec.arguments)\n      if (detached === undefined) {\n        throw new TypeError('tool execution arguments must be losslessly JSON-serializable')\n      }\n      const execution: MutableToolRunContext = { ...base, arguments: deepFreeze(detached) }\n      this.deferredContexts.set(execution, deferredContexts)\n      this.contentFinalizers.set(execution, finalizerFor())\n      this.cancellationStates.set(execution, {\n        callerSignal: signal,\n        bodyInvoked: false,\n      })\n      if (collapsed) {\n        // The collapse denies the call before the policy pipeline, but a\n        // pre-dispatch abort still keeps the established cancellation\n        // contract: `prepare`'s caller-cancellation check is skipped for\n        // final-results, so honor the abort here instead of surfacing\n        // `UNKNOWN_TOOL` on an already-cancelled call.\n        if (signal.aborted) {\n          return { kind: 'final-result', exec: execution, result: toolAbortedBeforeDispatchResult() }\n        }\n        // The name IS visible here, so the denial carries the route the model","sourceCodeStart":1396,"sourceCodeEnd":1432,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/core/tools/src/index.ts#L1396-L1432","documentation":"Error \"tool execution arguments must be losslessly JSON-serializable\" thrown in deepseek-ai/deepseek-harness.","triggerScenarios":"Thrown at packages/core/tools/src/index.ts:1414 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}