can1357/oh-my-pi · error

Generated whenToUse must start with 'Use this agent when...'

Error message

Generated whenToUse must start with 'Use this agent when...'

What it means

parseGeneratedAgentSpec validates the output of an LLM that drafts new agent definitions in the agents hub. The LLM-proposed whenToUse field must begin with the exact phrase 'Use this agent when' (case-insensitive) so generated agent descriptions follow a consistent, recognizable template. If the model returns a description in any other phrasing, this error is thrown and the spec is rejected.

Source

Thrown at packages/coding-agent/src/modes/components/agents-hub.ts:191

	const parsed = JSON.parse(extractJsonObject(raw)) as Partial<GeneratedAgentSpec>;
	if (!parsed || typeof parsed !== "object") {
		throw new Error("Model output is not a JSON object");
	}
	if (
		typeof parsed.identifier !== "string" ||
		typeof parsed.whenToUse !== "string" ||
		typeof parsed.systemPrompt !== "string"
	) {
		throw new Error("Model output is missing required fields (identifier, whenToUse, systemPrompt)");
	}
	const identifier = parsed.identifier.trim();
	const whenToUse = parsed.whenToUse.trim();
	const systemPrompt = parsed.systemPrompt.trim();
	if (!IDENTIFIER_PATTERN.test(identifier)) {
		throw new Error("Generated identifier is invalid (must be lowercase kebab-case, 2+ words)");
	}
	if (!whenToUse.toLowerCase().startsWith("use this agent when")) {
		throw new Error("Generated whenToUse must start with 'Use this agent when...'");
	}
	if (!systemPrompt) {
		throw new Error("Generated systemPrompt is empty");
	}
	return { identifier, whenToUse, systemPrompt };
}

function matchAgent(agent: HubAgent, query: string): boolean {
	const text = `${agent.name} ${agent.description} ${SOURCE_LABEL[agent.source]} ${agent.overrideModel ?? ""}`;
	return query
		.trim()
		.split(/\s+/)
		.every(token => fuzzyMatch(token, text).matches);
}

/**
 * The fullscreen agents hub component. Hosted via
 * `ui.showOverlay(..., { fullscreen: true })`; the host must call

View on GitHub (pinned to 9690622007)

Solutions

  1. Re-run the agent creation flow so the LLM regenerates the spec with the required prefix
  2. Edit the generated description manually so it starts with 'Use this agent when'
  3. Use a stronger model (configure the default/active model pattern) that follows the output template
  4. Relax the validation to accept any non-empty whenToUse if the strict template is not required

Example fix

// before
whenToUse = "Good for refactoring tasks"
// after
whenToUse = "Use this agent when refactoring tasks need automated handling"
Defensive patterns

Strategy: validation

Validate before calling

const whenToUse = (parsed.whenToUse ?? "").trim();
if (!whenToUse.toLowerCase().startsWith("use this agent when")) {
  throw new Error("whenToUse must start with 'Use this agent when'");
}

Type guard

function hasValidWhenToUse(s: unknown): s is { whenToUse: string } {
  return typeof s === "object" && s !== null && typeof (s as any).whenToUse === "string" &&
    (s as any).whenToUse.trim().toLowerCase().startsWith("use this agent when");
}

Try / catch

try {
  const spec = await hub.runAgentCreationArchitect(desc);
} catch (err) {
  if (err instanceof Error && err.message.includes("whenToUse")) {
    spec = { ...manualSpec, whenToUse: `Use this agent when ${desc}` };
  } else throw err;
}

Prevention

When it happens

Trigger: Calling #runAgentCreationArchitect (via the agents hub 'create agent' flow) when the architect LLM returns a whenToUse line that does not start with 'use this agent when' after trimming — e.g. it returns 'Helpful for refactoring...' or 'Best used when...'.

Common situations: Weak or non-instructed models ignoring the prompt template; model paraphrasing the description; prompt template updated but validation not; localization or verbose model output wrapping the phrase.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/0450cc87baa88941. Report an issue: GitHub.