{"record":{"id":"22292c63689a5931","repo":"mastra-ai/mastra","slug":"this-constructor-name-does-not-support-closing","errorCode":null,"errorMessage":"${this.constructor.name} does not support closing stdin","messagePattern":"(.+?) does not support closing stdin","errorType":"exception","errorClass":"UnsupportedStdinCloseError","httpStatus":null,"severity":"error","filePath":"packages/core/src/workspace/sandbox/process-manager/process-handle.ts","lineNumber":211,"sourceCode":"  abstract readonly pid: string;\n  /** Exit code, undefined while the process is still running */\n  abstract readonly exitCode: number | undefined;\n  /** The command that was spawned (set by the process manager) */\n  command?: string;\n  /** Kill the running process (SIGKILL). Returns true if killed, false if not found. */\n  abstract kill(): Promise<boolean>;\n  /** Send data to the process's stdin */\n  abstract sendStdin(data: string): Promise<void>;\n\n  /**\n   * Close the process's stdin, signaling EOF.\n   *\n   * Providers that cannot close stdin throw {@link UnsupportedStdinCloseError}.\n   * The default implementation is the unsupported case, so providers only\n   * override this when their transport exposes a stdin close primitive.\n   */\n  async closeStdin(): Promise<void> {\n    throw new UnsupportedStdinCloseError(`${this.constructor.name} does not support closing stdin`);\n  }\n\n  /**\n   * Wait for the process to finish and return the result.\n   *\n   * Optionally pass `onStdout`/`onStderr` callbacks to stream output chunks\n   * while waiting. The callbacks are automatically removed when `wait()`\n   * resolves, so there's no cleanup needed by the caller.\n   *\n   * Optionally pass an `abortSignal` to couple the blocking wait to a caller\n   * lifetime: on abort the process is killed (mirroring the spawn-time\n   * `abortSignal` convention in {@link CommandOptions}), which lets the wait\n   * settle with the killed process's result instead of blocking forever.\n   *\n   * Subclasses implement `wait()` with platform-specific logic; the base\n   * constructor wraps it to handle the optional streaming callbacks.\n   */\n  async wait(_options?: {","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workspace/sandbox/process-manager/process-handle.ts#L193-L229","documentation":"ProcessHandle.closeStdin() default implementation throws UnsupportedStdinCloseError because the provider's transport has no stdin-close primitive. Providers only override closeStdin when their transport actually supports signaling EOF on stdin.","triggerScenarios":"Calling processHandle.closeStdin() (often via the `writer` helper when done writing) on a process spawned by a provider that doesn't support closing stdin — e.g. certain remote/exec-based sandbox transports.","commonSituations":"Using a generic interactive-process helper (write then closeStdin) across sandbox providers, one of which lacks stdin close; expecting closeStdin to terminate the process instead of using kill/wait.","solutions":["Feature-detect: only call closeStdin if the provider documents/advertises support.","Wrap in try-catch for UnsupportedStdinCloseError and fall back to kill() or wait().","Restructure the interaction to not require EOF (e.g. length-prefixed protocol, explicit exit command).","If you own the provider, override closeStdin() with the transport's native close primitive."],"exampleFix":"// before\nawait handle.write(input);\nawait handle.closeStdin();\n// after\nawait handle.write(input);\ntry {\n  await handle.closeStdin();\n} catch (e) {\n  if (e.name !== 'UnsupportedStdinCloseError') throw e;\n  // provider cannot signal EOF; rely on protocol or kill()\n}","handlingStrategy":"try-catch","validationCode":"const supportsStdinClose = typeof (provider.prototype ?? provider).closeStdin === 'function' &&\n  !/UnsupportedStdinCloseError/.test((provider.prototype ?? provider).closeStdin.toString());","typeGuard":"function supportsStdinClose(h: object): h is { closeStdin(): Promise<void> } {\n  return typeof (h as any).closeStdin === 'function' &&\n    !/UnsupportedStdinCloseError/.test((h as any).closeStdin.toString());\n}","tryCatchPattern":"await handle.write(input);\ntry {\n  await handle.closeStdin();\n} catch (e) {\n  if (e.name !== 'UnsupportedStdinCloseError') throw e;\n  await handle.kill(); // or rely on protocol-level termination\n}","preventionTips":["Feature-detect stdin-close support per provider before using interactive write loops.","Design process protocols that terminate without requiring stdin EOF (sentinel token, explicit exit command).","Document provider capabilities and gate helper code on them."],"tags":["process","stdin","unsupported-operation"],"backgroundTag":"operation-not-supported","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}