affaan-m/ECC · error · Error

launcherCommand must be a non-empty string

Error message

launcherCommand must be a non-empty string

What it means

renderTemplate validates that the launcherCommand template is a non-empty string before substituting {variable} placeholders. It throws when the template is undefined, empty, or whitespace-only. This is the entry-point guard for generating worker launcher commands in the tmux orchestrator.

Solutions

  1. Provide a non-empty launcherCommand template in the config, e.g. 'claude --task {task} --worktree {worktreePath}'.
  2. Check the config loading path for silently producing '' or undefined and add a load-time check.
  3. Fall back to a known-good default template when the config value is empty.
  4. Validate config with a schema (e.g. zod) requiring launcherCommand: z.string().min(1).

Example fix

// before
renderTemplate(config.launcherCommand, vars); // config.launcherCommand === ''
// after
const template = config.launcherCommand || 'claude --task {task}';
renderTemplate(template, vars);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof launcherCommand !== 'string' || launcherCommand.trim().length === 0) throw new Error('launcherCommand is required in config');

Type guard

const hasTemplate = (c) => typeof c?.launcherCommand === 'string' && c.launcherCommand.trim().length > 0;

Try / catch

try {
  renderTemplate(template, vars);
} catch (e) {
  if (String(e.message) === 'launcherCommand must be a non-empty string') {
    console.error('launcherCommand missing/empty in orchestration config');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling renderTemplate(undefined, vars) or renderTemplate(' ', vars); passing config.launcherCommand when that config key was never set; spreading a config object where launcherCommand is absent.

Common situations: Omitting launcherCommand from the orchestration config; a config loader that returns an empty string on parse failure; renaming the config key so the template no longer reaches renderTemplate.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/6987e450e24f5170. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/tmux-worktree-orchestrator.js:18

'use strict';

const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');

function slugify(value, fallback = 'worker') {
  const normalized = String(value || '')
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '');
  return normalized || fallback;
}

function renderTemplate(template, variables) {
  if (typeof template !== 'string' || template.trim().length === 0) {
    throw new Error('launcherCommand must be a non-empty string');
  }

  return template.replace(/\{([a-z_]+)\}/g, (match, key) => {
    if (!(key in variables)) {
      throw new Error(`Unknown template variable: ${key}`);
    }
    return String(variables[key]);
  });
}

function shellQuote(value) {
  return `'${String(value).replace(/'/g, `'\\''`)}'`;
}

function formatCommand(program, args) {
  return [program, ...args.map(shellQuote)].join(' ');
}

View on GitHub (pinned to 8321021c54)