{"record":{"id":"e7339c75f4e8e176","repo":"actualbudget/actual","slug":"no-update-fields-provided-use-name-or-hidden-e7339c","errorCode":null,"errorMessage":"No update fields provided. Use --name or --hidden.","messagePattern":"No update fields provided\\. Use --name or --hidden\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/category-groups.ts","lineNumber":64,"sourceCode":"          printOutput({ id }, opts.format);\n        },\n        { mutates: true },\n      );\n    });\n\n  groups\n    .command('update <id>')\n    .description('Update a category group')\n    .option('--name <name>', 'New group name')\n    .option('--hidden <bool>', 'Set hidden status')\n    .action(async (id: string, cmdOpts) => {\n      const fields: Record<string, unknown> = {};\n      if (cmdOpts.name !== undefined) fields.name = cmdOpts.name;\n      if (cmdOpts.hidden !== undefined) {\n        fields.hidden = parseBoolFlag(cmdOpts.hidden, '--hidden');\n      }\n      if (Object.keys(fields).length === 0) {\n        throw new Error('No update fields provided. Use --name or --hidden.');\n      }\n      const opts = program.opts();\n      await withConnection(\n        opts,\n        async () => {\n          await api.updateCategoryGroup(id, fields);\n          printOutput({ success: true, id }, opts.format);\n        },\n        { mutates: true },\n      );\n    });\n\n  groups\n    .command('delete <id>')\n    .description('Delete a category group')\n    .option('--transfer-to <id>', 'Transfer transactions to this category ID')\n    .action(async (id: string, cmdOpts) => {\n      const opts = program.opts();","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/cli/src/commands/category-groups.ts#L46-L82","documentation":"The category-groups CLI `update` command likewise requires at least one of --name or --hidden. With no fields the command throws instead of issuing an empty update via api.updateCategoryGroup.","triggerScenarios":"Running `actual-cli category-groups update <id>` with no flags; flags dropped by shell expansion of empty variables; typos in option names.","commonSituations":"Automation pipelines parameterizing updates where all parameters happened to be empty; users expecting an id-only command to toggle something; mixing up the categories and category-groups commands.","solutions":["Provide --name and/or --hidden: `category-groups update <id> --name \"Bills\"`.","Verify flags with `category-groups update --help`.","Skip the call entirely if there is nothing to change."],"exampleFix":"// before\nactual category-groups grp_1 --verbose\n// after\nactual category-groups update grp_1 --name \"Monthly Bills\" --hidden false","handlingStrategy":"validation","validationCode":"const flags: string[] = [];\nif (name) flags.push('--name', name);\nif (typeof hidden === 'boolean') flags.push('--hidden', String(hidden));\nif (flags.length === 0) throw new Error('Nothing to update: pass --name and/or --hidden');","typeGuard":"null","tryCatchPattern":"try {\n  await runCli(['category-groups', 'update', id, ...flags]);\n} catch (e) {\n  if (String(e.message).includes('No update fields provided')) {\n    console.warn('No group fields to update; skipping', id);\n  } else throw e;\n}","preventionTips":["Check --help for the exact option names on category-groups update.","Build flags dynamically and assert the array is non-empty before running.","Don't rely on the command to toggle defaults — pass explicit values.","Differentiate between category and category-group ids to hit the right subcommand."],"tags":["cli","validation","arguments","category-groups"],"backgroundTag":"invalid-command-argument","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}