Skip to content

[BUG] Multiple subcommands report read_only: true despite mutating state #528

@mike-perrone-headway

Description

@mike-perrone-headway

Describe the bug

Several subcommands report "read_only": true in pup --help output despite
performing side effects (creating, mutating, or executing resources).

All rows below were confirmed from pup --help JSON on pup 0.63.0:

Command Description (verbatim from pup --help)
pup cases comment Add a comment to a case
pup workflows run Execute a workflow via API trigger (requires DD_API_KEY + DD_APP_KEY)
pup runbooks run Execute a runbook
pup synthetics tests run Run synthetic tests (requires DD_API_KEY + DD_APP_KEY)
pup feature-flags enable Enable a feature flag in an environment
pup feature-flags disable Disable a feature flag in an environment
pup feature-flags exposure start Start an exposure schedule
pup feature-flags exposure stop Stop an exposure schedule
pup feature-flags exposure pause Pause an exposure schedule
pup feature-flags exposure resume Resume an exposure schedule
pup notebooks edit Append cells to an existing notebook (reads current notebook first, then appends)
pup software-catalog entities upsert Create or update entities from a JSON file
pup software-catalog kinds upsert Create or update a kind from a JSON file
pup costs ccm budgets upsert Create or update a budget from a JSON file
pup costs ccm custom-costs upload Upload a custom cost file
pup costs ccm tag-descriptions upsert Create or update a tag description
pup costs ccm tag-descriptions generate AI-generate a description for a tag key
pup app-builder publish Publish an App Builder application
pup app-builder unpublish Unpublish an App Builder application
pup users seats users unassign Unassign seats from users
pup scorecards outcomes batch-create Create or update outcomes in batch from a JSON file

To Reproduce

Run pup's self-describing help and filter for read_only: true leaves whose
verb implies a mutation:

pup --help | jq '
  [.. | objects | select(.full_path? and .read_only == true and ((.subcommands // []) | length == 0))
   | {full_path, description, read_only}]
   | map(select(.full_path | test("(^| )(run|enable|disable|edit|upsert|publish|unpublish|unassign|upload|comment|start|stop|pause|resume|batch-create|generate)$")))
'

Sample output (excerpt):

[
  {
    "full_path": "workflows run",
    "description": "Execute a workflow via API trigger (requires DD_API_KEY + DD_APP_KEY)",
    "read_only": true
  },
  {
    "full_path": "feature-flags enable",
    "description": "Enable a feature flag in an environment",
    "read_only": true
  },
  {
    "full_path": "notebooks edit",
    "description": "Append cells to an existing notebook (reads current notebook first, then appends)",
    "read_only": true
  },
  {
    "full_path": "app-builder publish",
    "description": "Publish an App Builder application",
    "read_only": true
  },
  {
    "full_path": "costs ccm custom-costs upload",
    "description": "Upload a custom cost file",
    "read_only": true
  }
]

The mismatch is plainly visible: the description states the command mutates
state, while read_only: true claims it does not.

Expected behavior

read_only: true should mean "no server-side state change." Mutating verbs
(run, enable, disable, edit, upsert, publish, unpublish, unassign, upload,
comment, start, stop, pause, resume, batch-create, generate) should be
read_only: false.

If the current intent of the flag is something narrower (e.g. "doesn't require
write API scope"), consider renaming it or adding a separate mutates_state /
has_side_effects field so the read-only flag reflects what its name implies.

Environment

  • OS: macOS (darwin 25.5.0, arm64)
  • Pup version: 0.63.0 (latest in Homebrew tap)
  • Authentication method: OAuth2

Claude-generated with human guidance; reviewed by the submitter before filing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions