eyaltoledano/claude-task-master · error
INVALID_MODEL_ID
INVALID_MODEL_ID
Error message
Invalid model ID: ${modelId}. Must be a non-empty string. What it means
setModel() requires a non-empty, non-whitespace string model ID. Before doing any config or provider lookup it validates typeof modelId === 'string' && modelId.trim() !== '', and returns this structured failure if not. It means the caller passed undefined/null/empty string (or a non-string) as the --model-id value.
Source
Thrown at scripts/modules/task-manager/models.js:420
}
// Validate role
if (!['main', 'research', 'fallback'].includes(role)) {
return {
success: false,
error: {
code: 'INVALID_ROLE',
message: `Invalid role: ${role}. Must be one of: main, research, fallback.`
}
};
}
// Validate model ID
if (typeof modelId !== 'string' || modelId.trim() === '') {
return {
success: false,
error: {
code: 'INVALID_MODEL_ID',
message: `Invalid model ID: ${modelId}. Must be a non-empty string.`
}
};
}
try {
const availableModels = getAvailableModels(projectRoot);
const currentConfig = getConfig(projectRoot);
let determinedProvider = null; // Initialize provider
let warningMessage = null;
// Find the model data in internal list
// If we have a provider hint, search for exact provider+model match
// Otherwise, just search by model ID (will get first match)
let modelData;
if (providerHint) {
// Search for model with specific provider
modelData = availableModels.find(View on GitHub (pinned to c0c98d367c)
Solutions
- Re-run the command with an explicit non-empty model id, e.g. `task-master models --set-main --openrouter anthropic/claude-sonnet-4`.
- In scripts, check the value before calling: if (typeof modelId === 'string' && modelId.trim()) await setModel(modelId, 'main', root).
- If a shell/env variable supplies the id, verify it is exported and non-empty (`echo "$MODEL_ID"`) and add a default like ${MODEL_ID:-anthropic/claude-sonnet-4}.
Example fix
// before
await setModel(process.env.MODEL_ID, 'main', projectRoot); // undefined if env var missing
// after
const modelId = process.env.MODEL_ID?.trim();
if (!modelId) throw new Error('MODEL_ID env var must be set');
await setModel(modelId, 'main', projectRoot); Defensive patterns
Strategy: validation
Validate before calling
function canSetModel(modelId) {
return typeof modelId === 'string' && modelId.trim() !== '';
}
// before calling:
if (!canSetModel(modelId)) throw new Error('modelId must be a non-empty string'); Type guard
function isNonEmptyString(v) {
return typeof v === 'string' && v.trim().length > 0;
}
if (isNonEmptyString(modelId)) {
await setModel(modelId, 'main', projectRoot);
} Try / catch
try {
const res = await setModel(modelId, 'main', projectRoot);
if (!res.success && res.error?.code === 'INVALID_MODEL_ID') {
console.error('Provide a non-empty --model-id value, e.g. --openrouter vendor/model');
}
} catch (e) {
console.error('Unexpected setModel failure:', e.message);
} Prevention
- Never interpolate raw env vars into modelId without a fallback/default value.
- Validate CLI arguments (non-empty string) in your wrapper before calling setModel.
- Use a constant or enum of allowed model ids instead of free-form strings in automation.
- Add a shell guard: : "${MODEL_ID:?MODEL_ID must be set}" before invoking task-master commands.
When it happens
Trigger: Calling setModel(modelId, role, projectRoot) with modelId = undefined, null, '', ' ', a number, or an object — e.g. the CLI flag --model-id was omitted or the flag was given without a value so the parsed argument is empty.
Common situations: Running `task-master models --set-main` without `--openrouter=<id>`/`--model-id` value; a shell variable holding the model id being unset/empty ($MODEL_ID with no default); scripting that interpolates a blank env var; typos where the value lands in the wrong flag.
Related errors
- INVALID_RESPONSE_LANGUAGE
- Invalid maxAttempts value: ${maxAttempts}. Must be a positiv
- MISSING_CONFIGURATION
- INVALID_INPUT
- Unknown provider '${providerName}' for API key resolution.
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/e011468a20a7f04a.
Report an issue: GitHub.