{"record":{"id":"ad95ac55af4bfdb7","repo":"different-ai/openwork","slug":"extensions-add-name-required","errorCode":"extensions.add_name_required","errorMessage":"extensions.add_name_required","messagePattern":"extensions\\.add_name_required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/app/src/react-app/domains/settings/state/extensions-store.ts","lineNumber":2246,"sourceCode":"      }\n      await refreshSkills({ force: true });\n    } catch (error) {\n      const message = error instanceof Error ? error.message : t(\"skills.unknown_error\");\n      options.setError(addOpencodeCacheHint(message));\n    } finally {\n      options.setBusy(false);\n    }\n  }\n\n  async function createLibraryItem(\n    kind: LibraryAuthorableKind,\n    input: CreateLibraryItemInput,\n  ): Promise<string> {\n    const description = input.description.trim();\n    const instructions = input.instructions.trim();\n    const drafts = input.components?.filter((component) => component.name.trim() && component.content.trim()) ?? [];\n    if (!input.name.trim()) {\n      throw new Error(t(\"extensions.add_name_required\"));\n    }\n    if (kind === \"mcp\") {\n      if (!instructions) {\n        throw new Error(t(\"extensions.add_mcp_url_required\"));\n      }\n    } else if (kind !== \"plugin\") {\n      if (!description) {\n        throw new Error(t(\"extensions.add_description_required\"));\n      }\n      if (!instructions) {\n        throw new Error(t(\"extensions.add_instructions_required\"));\n      }\n    }\n    if (kind === \"plugin\" && drafts.length === 0) {\n      throw new Error(t(\"extensions.add_plugin_component_required\"));\n    }\n\n    const settings = readDenSettings();","sourceCodeStart":2228,"sourceCodeEnd":2264,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/domains/settings/state/extensions-store.ts#L2228-L2264","documentation":"createLibraryItem validates the new library item (skill/command/agent/mcp/plugin) before talking to the Den API. A missing name is the first check; the localized validation message t('extensions.add_name_required') is thrown as the Error message so UI code can match on the i18n key string.","triggerScenarios":"Calling createLibraryItem(kind, input) with input.name empty or whitespace-only ('', '   ') — the trim() leaves an empty string.","commonSituations":"Submitting the 'Add to library' form without typing a name; programmatically building CreateLibraryItemInput and forgetting the name field; copying an input object where name was nulled by a form reset.","solutions":["Set a non-empty name on the input before calling createLibraryItem.","Validate in the form/UI layer (disable submit until name.trim() is non-empty) so the API-layer error never fires.","If the error appears despite a filled field, check for stray whitespace-only input or a binding bug where input.name is undefined at call time."],"exampleFix":"// before\nawait createLibraryItem('skill', { name: '', description: '...', instructions: '...' });\n// after\nconst name = form.name.trim();\nif (!name) { showFieldError('name', t('extensions.add_name_required')); return; }\nawait createLibraryItem('skill', { ...form, name });","handlingStrategy":"validation","validationCode":"const name = input.name.trim();\nif (!name) { showFieldError('name', t('extensions.add_name_required')); return; }","typeGuard":null,"tryCatchPattern":"try {\n  await createLibraryItem(kind, input);\n} catch (e) {\n  if (e instanceof Error && e.message === t('extensions.add_name_required')) {\n    showFieldError('name', e.message);\n  } else throw e;\n}","preventionTips":["Trim user input before constructing the API payload","Disable submit until required fields pass trim checks","Match thrown i18n keys to inline field errors","Write a validation unit test per required field"],"tags":["validation","i18n","form"],"backgroundTag":"missing-required-argument","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}