github/copilot-sdk · error

Factory phase titles must not be empty

Error message

Factory phase titles must not be empty

What it means

validatePhases rejects factory phase definitions whose title is empty or consists only of whitespace. Phase titles identify stages of a factory and are used for display and uniqueness checks, so an empty title is considered invalid metadata and fails at defineFactory time.

Solutions

  1. Give every phase a non-empty title string with at least one non-whitespace character.
  2. Validate titles before calling defineFactory, especially when they come from data files or user input.
  3. Fix the data source (translation table, JSON, spreadsheet) that is producing empty titles.
  4. Trim and check user-supplied titles at input boundaries.

Example fix

// before
defineFactory({ name: 'build', phases: [{ title: '   ', steps: [] }] });
// after
defineFactory({ name: 'build', phases: [{ title: 'Compile', steps: [] }] });
Defensive patterns

Strategy: validation

Validate before calling

for (const p of phases) {
  if (typeof p.title !== 'string' || p.title.trim().length === 0) throw new TypeError(`Phase title must be non-empty (got ${JSON.stringify(p.title)})`);
}

Type guard

function hasTitle(p) { return typeof p.title === 'string' && p.title.trim().length > 0; }

Try / catch

try {
  defineFactory(meta);
} catch (e) {
  if (e.message === 'Factory phase titles must not be empty') console.error('A phase is missing a title');
  throw e;
}

Prevention

When it happens

Trigger: Calling defineFactory with a phase whose title is '' or contains only spaces/newlines (title.trim().length === 0). Also occurs when titles are derived from data (e.g. a missing i18n string or a field that failed to map) and end up as empty strings.

Common situations: Localization files missing a translation key resulting in ''; spreadsheet/JSON-driven phase generation with blank rows; refactoring that removed a default title; accidental whitespace-only strings from user input.

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 github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/d41848b79843b83c. Report an issue: GitHub.

Appendix: source

Thrown at nodejs/src/factory.ts:468

        const maxNanoAiu = Math.round(limits.maxAiCredits * NANO_AIU_PER_AIU);
        if (
            !Number.isFinite(limits.maxAiCredits) ||
            limits.maxAiCredits <= 0 ||
            !Number.isSafeInteger(maxNanoAiu) ||
            maxNanoAiu < 1
        ) {
            throw new Error(
                'Factory limit "maxAiCredits" must be a positive, finite number that rounds to a safe positive integer nano-AIU ceiling'
            );
        }
    }
}

function validatePhases(meta: FactoryMeta): void {
    const titles = new Set<string>();
    for (const phase of meta.phases) {
        if (phase.title.trim().length === 0) {
            throw new Error("Factory phase titles must not be empty");
        }
        if (titles.has(phase.title)) {
            throw new Error(`Factory phase title "${phase.title}" is declared more than once`);
        }
        titles.add(phase.title);
    }
}

/**
 * Defines an extension-authored factory and returns an opaque registration handle.
 *
 * @experimental Part of the experimental Agent Factories surface and may
 * change or be removed in future SDK or CLI releases.
 */
export function defineFactory<
    TArgs extends JsonValue = JsonValue,
    TResult extends JsonValue | void = JsonValue | void,
>(definition: FactoryDefinition<TArgs, TResult>): FactoryHandle<TArgs, TResult> {

View on GitHub (pinned to cd8cf15dc3)