{"record":{"id":"f2f790c733d8fe8f","repo":"multica-ai/multica","slug":"command-name-is-required","errorCode":null,"errorMessage":"command_name is required","messagePattern":"command_name is required","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/internal/handler/runtime_profile.go","lineNumber":105,"sourceCode":"\t}\n\tclean := make([]string, 0, len(args))\n\tfor _, a := range args {\n\t\t// fixed_args are launch flags inherited by every agent on the runtime;\n\t\t// blank entries are always a client mistake.\n\t\tif strings.TrimSpace(a) == \"\" {\n\t\t\treturn nil, errors.New(\"fixed_args entries must be non-empty\")\n\t\t}\n\t\tif strings.ContainsRune(a, '\\x00') {\n\t\t\treturn nil, errors.New(\"fixed_args entries cannot contain NUL bytes\")\n\t\t}\n\t\tclean = append(clean, a)\n\t}\n\treturn json.Marshal(clean)\n}\n\nfunc validateRuntimeProfileCommandName(commandName string) error {\n\tif commandName == \"\" {\n\t\treturn errors.New(\"command_name is required\")\n\t}\n\tif strings.ContainsAny(commandName, \" \\t\\r\\n\") {\n\t\treturn errors.New(\"command_name must be a single executable token; put arguments in fixed_args\")\n\t}\n\tif strings.ContainsRune(commandName, '\\x00') {\n\t\treturn errors.New(\"command_name cannot contain NUL bytes\")\n\t}\n\treturn nil\n}\n\ntype createRuntimeProfileRequest struct {\n\tDisplayName    string   `json:\"display_name\"`\n\tProtocolFamily string   `json:\"protocol_family\"`\n\tCommandName    string   `json:\"command_name\"`\n\tDescription    *string  `json:\"description\"`\n\tFixedArgs      []string `json:\"fixed_args\"`\n\tEnabled        *bool    `json:\"enabled\"`\n}","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/handler/runtime_profile.go#L87-L123","documentation":"validateRuntimeProfileCommandName requires a non-empty command_name on runtime profile create/update. The command is what gets exec'd for every agent using the profile, and the column has no useful default, so omitting it is rejected immediately. Related checks in the same function enforce the single-token and no-NUL rules.","triggerScenarios":"POST /runtime-profiles (or PUT) with command_name missing from the JSON body, set to \"\", or an update payload that only patches display_name while the server expects the full object including command_name.","commonSituations":"Edit forms that send only changed fields against a full-replace endpoint; creation UI where the command input was left blank; scripts cloning a profile but forgetting to copy command_name.","solutions":["Include a non-empty command_name, e.g. \"node\", \"npx\", \"docker\"","Check whether the endpoint is full-replace — if so, always send the complete profile object on update","Add required-field validation in the client form before submit"],"exampleFix":"// before\n{ display_name: \"Local runner\" }\n// after\n{ display_name: \"Local runner\", command_name: \"npx\", fixed_args: [\"-y\", \"some-agent\"] }","handlingStrategy":"validation","validationCode":"if (!commandName || commandName.trim() === '') {\n  setFormError('Executable is required');\n  return;\n}","typeGuard":"function hasCommandName(s: unknown): s is string {\n  return typeof s === 'string' && s.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Mark command_name required in the form schema","Know whether the update endpoint is full-replace; always send complete objects if so","Clone operations must copy every required field"],"tags":["validation","runtime-profile","required-field"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}