{"record":{"id":"ef2b0e44c91144cd","repo":"deepseek-ai/deepseek-harness","slug":"session-create-failed-rpcerror-code-rpcerro","errorCode":null,"errorMessage":"session create failed: ${rpcError.code}: ${rpcError.message}","messagePattern":"session create failed: (.+?): (.+?)","errorType":"exception","errorClass":"SessionCreateError","httpStatus":null,"severity":"error","filePath":"packages/client/runtime/src/client/sessions/service.ts","lineNumber":487,"sourceCode":"  /** Drop generation-scoped live interaction state the moment a connection generation dies. */\n  handleDisconnected(): void {\n    this.manager.handleDisconnected()\n  }\n\n  /**\n   * Create a session on the host. Resolution guarantee: by the time the\n   * promise resolves, the created session is in the list store and\n   * {@link SessionRuntime.binding} resolves it — callers (New Session\n   * draft hand-off) may address the scope synchronously, without waiting a\n   * notifier flush. The synchronous projection below makes this structural\n   * rather than an accident of microtask ordering.\n   * @param opts - target workspace or directory and an optional preallocated id.\n   * @returns the new session id.\n   * @throws {SessionCreateError} with the requested id.\n   */\n  async create(opts: { workspaceId?: WorkspaceId; cwd?: string; sessionId?: SessionId } = {}): Promise<SessionId> {\n    const result = await this.manager.create(opts)\n    if (!result.ok) throw new SessionCreateError(result.error, opts.sessionId)\n    this.projectList()\n    return result.value.sessionId\n  }\n\n  /**\n   * Fork a session from a completed-turn prefix of the source (same\n   * synchronous-addressability guarantee as {@link SessionRuntime.create}:\n   * on resolution the child is in the list store and open() can target it).\n   * @param opts - source session id, the optional event seq anchoring the\n   *   cut (the boundary is the first turn/end at or after it; an in-log\n   *   anchor in an open turn is unavailable rather than clipped backward),\n   *   and whether to increment an inherited durable title before resolving.\n   *   A fractional anchor floors to a real event seq: the frozen nodes of an\n   *   interrupted turn carry flow-ordering seqs between two events, and the\n   *   wire takes integers only.\n   * @returns the child session id.\n   * @throws {SessionForkError} with the source id.\n   * @throws {Error} when a requested child-title rename fails after creation.","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/client/runtime/src/client/sessions/service.ts#L469-L505","documentation":"sessions.create() forwards the create request over RPC and the host answered with a failed result; the client wraps the RpcError (code and message) in a SessionCreateError that also carries the requested sessionId when one was preallocated. Reaching this error means a host-side rejection came back as a Result, not a transport throw — the embedded code says why (unknown workspace, inaccessible cwd, duplicate id, host refusal). On success the same path refreshes the project list, so a failed create also means that refresh did not happen.","triggerScenarios":"await sessions.create({ workspaceId, cwd, sessionId }) with a workspaceId absent from the host's current workspace set, a cwd the host cannot access, a sessionId that already exists host-side, or any other host refusal returned as a failed Result from manager.create().","commonSituations":"Using a workspace id captured before the host's workspace list changed; passing a local path that does not exist host-side; retrying a create with the same preallocated id after an earlier partial attempt; host permission or policy changes between listing and creating.","solutions":["Read the embedded RpcError code and message off the SessionCreateError to classify the refusal before acting","Refresh the workspace/project list and pass a workspaceId taken from that fresh list","Drop or re-mint the preallocated sessionId when the code indicates an id collision","Verify the cwd exists host-side and the connection is healthy, then retry once at most"],"exampleFix":"// before\nconst id = await sessions.create({ workspaceId, sessionId })\n\n// after — classify the host refusal instead of losing it\ntry {\n  const id = await sessions.create({ workspaceId, sessionId })\n} catch (error) {\n  if (error instanceof SessionCreateError) {\n    // error.message reads 'session create failed: <code>: <message>'; the requested id travels on the error\n    throw new Error(`cannot create session in workspace ${workspaceId}: ${error.message}`)\n  }\n  throw error\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await sessions.create(opts)\n} catch (error) {\n  if (error instanceof SessionCreateError) {\n    // inspect the embedded '<code>: <message>' text and the carried requested id;\n    // retry once only for transient classes, with a fresh preallocated id\n  }\n  throw error\n}","preventionTips":["Take workspaceId from a freshly listed workspace set, never from persisted UI state","Mint a new sessionId per create attempt instead of reusing one after failures","Verify the cwd exists on the host before sending it","Log the embedded RpcError code — it distinguishes workspace, cwd, and id-collision refusals"],"tags":["rpc","session-create","workspace","host-error"],"backgroundTag":"rpc-request-failed","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}