{"record":{"id":"49a0a4bdad272778","repo":"can1357/oh-my-pi","slug":"background-job-manager-unavailable-for-this-sessio","errorCode":null,"errorMessage":"Background job manager unavailable for this session.","messagePattern":"Background job manager unavailable for this session\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/bash.ts","lineNumber":816,"sourceCode":"\t#extractTextResult(result: AgentToolResult<BashToolDetails>): string {\n\t\treturn result.content.find(block => block.type === \"text\")?.text ?? \"\";\n\t}\n\n\t#startManagedBashJob(options: {\n\t\tcommand: string;\n\t\tcommandCwd: string;\n\t\ttimeoutMs: number | undefined;\n\t\ttimeoutSec: number | undefined;\n\t\trequestedTimeoutSec?: number;\n\t\tnotices?: readonly string[];\n\n\t\tresolvedEnv?: Record<string, string>;\n\t\tonUpdate?: AgentToolUpdateCallback<BashToolDetails>;\n\t\tforwardUpdates: boolean;\n\t}): ManagedBashJobHandle {\n\t\tconst manager = this.session.asyncJobManager;\n\t\tif (!manager) {\n\t\t\tthrow new ToolError(\"Background job manager unavailable for this session.\");\n\t\t}\n\n\t\tconst label = options.command.length > 120 ? `${options.command.slice(0, 117)}...` : options.command;\n\t\tlet latestText = \"\";\n\t\tlet forwardUpdates = options.forwardUpdates;\n\t\tconst completion = Promise.withResolvers<ManagedBashJobCompletion>();\n\n\t\tconst jobId = manager.register(\n\t\t\t\"bash\",\n\t\t\tlabel,\n\t\t\tasync ({ jobId, signal: runSignal, reportProgress }) => {\n\t\t\t\tconst { path: artifactPath, id: artifactId } = (await this.session.allocateOutputArtifact?.(\"bash\")) ?? {};\n\t\t\t\tconst tailBuffer = new TailBuffer(DEFAULT_MAX_BYTES);\n\t\t\t\tconst wallTimeStart = performance.now();\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await executeBash(options.command, {\n\t\t\t\t\t\tcwd: options.commandCwd,\n\t\t\t\t\t\tsessionKey: `${this.session.getSessionId?.() ?? \"\"}:async:${jobId}`,","sourceCodeStart":798,"sourceCodeEnd":834,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/bash.ts#L798-L834","documentation":"BashTool's #startManagedBashJob requires the session's AsyncJobManager to register and track background jobs. When session.asyncJobManager is undefined, the tool cannot create a managed job and throws this ToolError immediately instead of starting the background command. It guards the auto-backgrounding path where the command would otherwise silently lose tracking, output delivery, and cancellation.","triggerScenarios":"Calling the bash tool with async=true (or a command that triggers auto-backgrounding) on a session constructed without an AsyncJobManager — e.g. embedding the SDK with a minimal session factory, or a session mode that never instantiates the job manager.","commonSituations":"SDK/custom-session embedders omitting the async job manager wiring; headless or restricted runtimes where background jobs are intentionally disabled; sessions created by third-party harnesses predating the async job manager feature.","solutions":["Construct the session with an AsyncJobManager attached (session.asyncJobManager set) before invoking the bash tool.","If background execution is not desired, don't request it: pass async=false and disable autoBackground in settings so the foreground path runs.","Check session capabilities up front and surface a clear 'background not supported in this host' message instead of reaching the tool call."],"exampleFix":"// before: minimal session without job manager\nconst session = createSession({ /* no asyncJobManager */ });\nawait bash.execute(id, { command: \"npm test\", async: true });\n\n// after: wire the job manager\nconst session = createSession({ asyncJobManager: new AsyncJobManager() });\nawait bash.execute(id, { command: \"npm test\", async: true });","handlingStrategy":"validation","validationCode":"if (!session.asyncJobManager) {\n  throw new Error(\"This session has no async job manager; background bash is unavailable.\");\n}\nawait bash.execute(id, { command, async: true });","typeGuard":null,"tryCatchPattern":"try {\n  await bash.execute(id, { command, async: true });\n} catch (e) {\n  if (e instanceof ToolError && e.message.includes(\"job manager unavailable\")) {\n    // fall back to foreground execution\n    return bash.execute(id, { command });\n  }\n  throw e;\n}","preventionTips":["Always construct sessions through the factory that wires AsyncJobManager.","Check session.asyncJobManager before advertising background capabilities in your host UI.","Keep autoBackground disabled when the job manager is absent."],"tags":["background-jobs","session-config","async"],"backgroundTag":"job-manager-unavailable","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}