different-ai/openwork · error · ApiError
invalid_command_template
invalid_command_template
Error message
Command template is required
What it means
buildCommandContent validates that an upsert-command payload includes a non-empty template before writing the command's markdown frontmatter. An empty or whitespace-only template is rejected with a 400 ApiError.
Source
Thrown at apps/server/src/commands.ts:80
if (scope === "global") {
const dir = join(homedir(), ".config", "opencode", "commands");
return listCommandsInDir(dir, "global");
}
return listCommandsInDir(projectCommandsDir(workspaceRoot), "workspace");
}
export type UpsertCommandPayload = {
name: string;
description?: string;
template: string;
agent?: string;
model?: string | null;
subtask?: boolean;
};
export function buildCommandContent(payload: UpsertCommandPayload): { name: string; content: string } {
if (!payload.template || payload.template.trim().length === 0) {
throw new ApiError(400, "invalid_command_template", "Command template is required");
}
const sanitized = sanitizeCommandName(payload.name);
validateCommandName(sanitized);
const frontmatter = buildFrontmatter(normalizeCommandFrontmatter({
name: sanitized,
description: payload.description,
agent: payload.agent,
model: payload.model,
subtask: payload.subtask ?? false,
}));
const content = frontmatter + "\n" + payload.template.trim() + "\n";
return { name: sanitized, content };
}
export async function upsertCommand(
workspaceRoot: string,
payload: UpsertCommandPayload,
): Promise<string> {View on GitHub (pinned to 2b7df46e8a)
Solutions
- Include a non-empty template string in the payload before calling the upsert endpoint
- Trim-check the template on the client before submitting and show a form validation error
- If migrating from an older API version, add the template field that is now required
Example fix
// before
await api.upsertCommand({ name: "deploy", description: "Deploy the app" });
// after
await api.upsertCommand({ name: "deploy", description: "Deploy the app", template: "Run the deploy pipeline for $ARGUMENTS" }); Defensive patterns
Strategy: validation
Validate before calling
const parsed = UpsertSchema.safeParse(payload); if (!parsed.success) throw new Error(parsed.error.issues[0].message);
Prevention
- Share one Zod schema between client and server
- Trim template input before submit
- Show required-field errors in the form UI
When it happens
Trigger: Calling the command upsert API (or buildCommandContent directly) with payload.template omitted, null, or set to "" / " ".
Common situations: Client form submitted without filling the prompt body; API client sends only name/description; older clients predating a template-required schema change; JSON body missing the field due to serialization bugs.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/ea4159d311acf575.
Report an issue: GitHub.