Skip to content

Task tool fails with exclusivity error when invoked during a prompt #176

@astrobot-houston

Description

@astrobot-houston

Originally reported by @khoi in #175.

All community-submitted pull requests are automatically converted to issues (bugs) & discussions (feature requests, enhancements) where they can be triaged and prioritized. Once prioritized, a PR implementation is created automatically.

Describe the Bug

When the model-facing task tool is invoked during a prompt() call, it fails with an exclusivity error. The task tool internally calls the public session.task() API, which is guarded by runExclusive('task'). Since tool execution happens while the parent session is already inside runExclusive('prompt'), the exclusivity check rejects the call with:

[flue] Session "default" is already running prompt. Start another session for parallel conversation branches.

This means any agent that uses the task tool during a prompt cannot spawn child tasks, making the tool effectively unusable in its primary context.

Expected Behavior

The model-facing task tool should be able to create and run a child task while the parent session is inside a prompt() call, since spawning child tasks from within tool execution is the intended use case.

Steps to Reproduce

  1. Create a session with a createTaskSession callback configured.
  2. Start a prompt() call on the session (which enters runExclusive('prompt')).
  3. During tool execution within that prompt, invoke the task tool to spawn a child task.
  4. The call fails with Session "default" is already running prompt. Start another session for parallel conversation branches.

Minimal reproduction:

const session = new Session({
	name: 'default',
	storageKey: 'session',
	affinityKey: 'affinity',
	config,
	env,
	store: new InMemorySessionStore(),
	existingData: null,
	createTaskSession: async () =>
		({
			prompt: async (text: string) => ({ text }),
			getAssistantText: () => '',
			getLatestAssistantMessageId: () => undefined,
			close: () => {},
			abort: () => {},
		}) as Session,
});

(session as unknown as { activeOperation: string }).activeOperation = 'prompt';

await (
	session as unknown as {
		runTaskForTool: (
			params: { prompt: string },
			tools: [],
			role: undefined,
			model: undefined,
			thinkingLevel: undefined,
		) => Promise<unknown>;
	}
).runTaskForTool({ prompt: 'inspect the diff' }, [], undefined, undefined, undefined);
// Throws: Session "default" is already running prompt...

Original implementation from #175 by @khoi

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions