different-ai/openwork · error
name is required
Error message
name is required
What it means
deleteCommandFile sanitizes the name argument before constructing the <name>.md path inside the commands directory. If name is missing/empty or sanitizes to nothing, it throws 'name is required' to avoid deleting an undefined or dangerous path.
Source
Thrown at apps/desktop/electron/main.mjs:1536
.sort();
}
async function writeCommandFile(scope, projectDir, command) {
const safeName = sanitizeCommandName(command?.name);
if (!safeName) {
throw new Error("command.name is required");
}
const commandsDir = resolveCommandsDir(scope, projectDir);
await mkdir(commandsDir, { recursive: true });
const filePath = path.join(commandsDir, `${safeName}.md`);
await writeFile(filePath, serializeCommandFrontmatter({ ...command, name: safeName }), "utf8");
return execResult(true, `Wrote ${filePath}`);
}
async function deleteCommandFile(scope, projectDir, name) {
const safeName = sanitizeCommandName(name);
if (!safeName) {
throw new Error("name is required");
}
const commandsDir = resolveCommandsDir(scope, projectDir);
const filePath = path.join(commandsDir, `${safeName}.md`);
if (await pathExists(filePath)) {
await rm(filePath, { force: true });
}
return execResult(true, `Deleted ${filePath}`);
}
async function collectProjectSkillRoots(projectDir) {
const roots = [];
let current = path.resolve(projectDir);
while (true) {
const opencodeSkills = path.join(current, ".opencode", "skills");
const legacySkills = path.join(current, ".opencode", "skill");
const claudeSkills = path.join(current, ".claude", "skills");
View on GitHub (pinned to 2b7df46e8a)
Solutions
- Pass the exact command name as it appears in the commands directory listing.
- Verify the delete handler actually forwards the name (not an event object or index).
- Trim and sanity-check the name is non-empty before invoking.
- Re-list commands (listCommandNames) and delete using a fresh, valid name.
Example fix
// before
await deleteCommandFile("workspace", dir, undefined);
// after
await deleteCommandFile("workspace", dir, "run-tests"); Defensive patterns
Strategy: validation
Validate before calling
const safe = String(name ?? '').trim();
if (!safe || /[\\/]/.test(safe)) {
throw new Error('name must be a non-empty filename-safe string');
} Type guard
function isDeletableCommandName(name) {
return typeof name === 'string' && name.trim().length > 0;
} Prevention
- Bind the command name explicitly in delete handlers; never forward raw event objects.
- Re-list commands before delete to confirm the exact name exists.
- Use the filename-safe name, not a display label, when deleting.
When it happens
Trigger: Calling the command-delete API with name=undefined/null/empty string, or a name made only of characters stripped by sanitizeCommandName (slashes, whitespace).
Common situations: Deleting from a stale list where the command row lost its name, passing the command's display label (stripped to nothing) instead of its filename-safe name, or wiring the delete handler without binding the name argument.
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
- scope must be 'workspace' or 'global'
- t("providers.provider_id_required")
- invalid_command_template
- command.template is required
- projectDir is required
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/4c73d8414e94e61c.
Report an issue: GitHub.