Skip to content

bug: avoid executing Click callbacks during JSON capture preflight #338

Description

@codeforester

Problem

An attached command with an optional lifecycle JSON flag executes option callbacks and their close hooks twice on a normal human invocation. Merely offering JSON output changes native Click behavior. Callable defaults, custom parameter types, lazy resolvers, and resource hooks are also exposed to the extra resilient parse. This can repeat application work before the real command starts.

Verified evidence

Reviewed on 2026-09-12 at 7faf347a5b90969e169c88f3ac18e7202d142dd0; the local checkout matches GitHub main.

Create a click.command(name="probe") with click.option("--payload", default="hi", callback=callback). Have the callback append ctx.resilient_parsing to a list and register a ctx.call_on_close hook. Attach it to App(name="probe", lifecycle_options=LifecycleOptions(json=LifecycleOption("--json"))) and call run_app(command, []).

Observed callback flags: [True, False]; both close hooks execute. With run_app(command, ["--json"]), the callback executes only once ([False]). _click_lifecycle_value() calls make_context(..., resilient_parsing=True) and closes those contexts before actual invocation. Resilient parsing is not a side-effect-free parse. The command body itself executes once.

Sources:

Acceptance criteria

  • Resolve capture activation without executing consumer callbacks, defaults, converters, lazy loaders, or close hooks twice.
  • Retain auto-envvar, callable-default, nested default-map and explicit flag semantics from [v1.0] Preserve single-envelope JSON output for Click-derived activation #304.
  • Add public run_app subprocess/attachment regressions counting callbacks and cleanup hooks in human, JSON, early-error and lazy-tree modes.
  • Keep human and NDJSON output streaming.

Related work

Follow-up to closed #304 and #268; the previously tested activation cases pass, but callback multiplicity was not covered.

Project fields

  • Status: Backlog
  • Priority: P1
  • Area: CLI
  • Initiative: v1.0 Readiness
  • Size: M
  • Assignee: @codeforester
  • Milestone: v1.0.0
  • Target date: unscheduled

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething is not working

Type

Projects

  • Status
    Backlog

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions