eyaltoledano/claude-task-master · error · Error
Shell executor not yet implemented
Error message
Shell executor not yet implemented
What it means
Plain Error thrown by ExecutorFactory.create when options.type is 'shell'. The shell executor is a declared but unimplemented placeholder in the factory switch, so requesting it always throws. It is a library capability gap, not a runtime fault.
Source
Thrown at packages/tm-core/src/modules/execution/executors/executor-factory.ts:24
import { ClaudeExecutor } from '../executors/claude-executor.js';
import type { ExecutorOptions, ExecutorType, ITaskExecutor } from '../types.js';
export class ExecutorFactory {
private static logger = getLogger('ExecutorFactory');
/**
* Create an executor based on the provided options
*/
static create(options: ExecutorOptions): ITaskExecutor {
this.logger.debug(`Creating executor of type: ${options.type}`);
switch (options.type) {
case 'claude':
return new ClaudeExecutor(options.projectRoot, options.config);
case 'shell':
// Placeholder for shell executor
throw new Error('Shell executor not yet implemented');
case 'custom':
// Placeholder for custom executor
throw new Error('Custom executor not yet implemented');
default:
throw new Error(`Unknown executor type: ${options.type}`);
}
}
/**
* Get the default executor type based on available tools
*/
static async getDefaultExecutor(
projectRoot: string
): Promise<ExecutorType | null> {
// Check for Claude first
const claudeExecutor = new ClaudeExecutor(projectRoot);View on GitHub (pinned to c0c98d367c)
Solutions
- Use type: 'claude' which is the implemented executor
- Omit options.type and let the factory pick the default via getDefaultExecutorType()
- Check the installed @tm/core version / changelog for shell executor availability and upgrade when it ships
- If you need shell semantics, wrap your command in a script the Claude executor can run, or contribute a ShellExecutor implementing the Executor interface
- Validate user/config-supplied executor type against the supported set before calling create
Example fix
// before
const exec = ExecutorFactory.create({ type: 'shell', projectRoot });
// after
const exec = ExecutorFactory.create({ type: 'claude', projectRoot }); Defensive patterns
Strategy: validation
Validate before calling
type SupportedExecutor = 'claude';
function assertImplemented(t: string): asserts t is SupportedExecutor {
if (t !== 'claude') throw new Error(`Executor '${t}' not implemented; use 'claude'`);
} Type guard
const isImplementedExecutor = (t: unknown): t is 'claude' => typeof t === 'string' && t === 'claude';
Try / catch
try {
executor = ExecutorFactory.create({ type: 'shell', projectRoot });
} catch (e) {
if (e.message.includes('not yet implemented')) {
executor = ExecutorFactory.create({ type: 'claude', projectRoot });
} else throw e;
} Prevention
- Only pass executor types confirmed implemented in your installed version
- Check the changelog for shell/custom executor availability
- Never forward raw user config values as executor type without whitelisting
- Default to omitting type so the factory chooses a working executor
When it happens
Trigger: Calling ExecutorFactory.create({ type: 'shell', projectRoot }) (with or without config) — every such call throws unconditionally until the executor is implemented.
Common situations: Constructing an execution request with a hardcoded or config-driven executor type of 'shell'; following docs/examples that mention shell execution before the feature shipped; a user config file specifying shell as the preferred executor.
Related errors
- Custom executor not yet implemented
- `Unknown executor type: ${options.type}`
- No default executor available
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/5fb82bc0869a0c4d.
Report an issue: GitHub.