Skip to content

Emit structured local runtime errors in JSON mode - #510

Closed
sdairs wants to merge 9 commits into
issue-458-disable-script-telemetryfrom
issue-475-local-structured-errors
Closed

Emit structured local runtime errors in JSON mode#510
sdairs wants to merge 9 commits into
issue-458-disable-script-telemetryfrom
issue-475-local-structured-errors

Conversation

@sdairs

@sdairs sdairs commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • emit one structured local runtime error object on stderr for explicit --json and detected-agent mode while leaving stdout empty
  • define and document a closed 11-code taxonomy with fixed, non-interpolated recovery commands
  • preserve human error text, existing exit codes, and native child stdout/stderr/status behavior
  • redact opaque startup, download, filesystem, and fallback diagnostics and keep telemetry unchanged

Closes #475

Schema

{
  "error": {
    "code": "server_not_found",
    "message": "Server 'default' not found",
    "command": "clickhousectl local server list"
  }
}

The README pins the full code set: server_not_found, server_not_running, server_running, invalid_version, version_unavailable, port_in_use, startup_exit, startup_timeout, download_failed, io_error, and bounded fallback local_error. Progress is silent in structured mode so stderr remains one JSON object on failure. Clap usage errors and native protocol/child output remain outside the envelope.

Verification

  • cargo fmt --all --check
  • cargo build -p clickhousectl
  • cargo check -p clickhousectl --no-default-features
  • cargo test -p clickhousectl (776 passed)
  • cargo clippy -p clickhousectl --all-targets -- -D warnings
  • subprocess matrices assert exact schema, stderr/stdout placement, status, agent detection, human output, redaction, startup/download boundaries, and native child passthrough

Stack

Comment thread crates/clickhousectl/src/main.rs
@sdairs
sdairs force-pushed the issue-475-local-structured-errors branch from a198463 to 94ecf57 Compare August 25, 2026 12:11
@sdairs
sdairs force-pushed the issue-470-local-client-query-multiplicity branch from 133d21b to 6774653 Compare August 25, 2026 12:11
@sdairs
sdairs changed the base branch from issue-470-local-client-query-multiplicity to issue-458-disable-script-telemetry August 25, 2026 12:13
Comment thread crates/clickhousectl/src/telemetry.rs
Comment thread crates/clickhousectl/src/local/postgres.rs

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High local/postgres.rs:107

A stopped existing instance cannot be resumed when the caller supplies an occupied --port; preflight_start_options returns PostgresValidation before start reaches resume_existing. The resume path intentionally ignores supplied settings and uses the stored port, so defer explicit-port availability validation until the fresh-create path.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @crates/clickhousectl/src/local/postgres.rs around line 107:

A stopped existing instance cannot be resumed when the caller supplies an occupied `--port`; `preflight_start_options` returns `PostgresValidation` before `start` reaches `resume_existing`. The resume path intentionally ignores supplied settings and uses the stored port, so defer explicit-port availability validation until the fresh-create path.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change. The earlier PR #486 review deliberately retained validation of supplied ports before recovery/Docker work per issue #460. Resume defers auto-selection only when --port is omitted; an occupied explicit port is an invalid invocation even if the stored instance would otherwise resume with a different binding. Existing regressions pin both behaviors.

Comment thread crates/clickhousectl/src/local/output.rs
Comment thread crates/clickhousectl/src/local/output.rs
Comment thread crates/clickhousectl/src/local/postgres.rs Outdated

@iskakaushik iskakaushik left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sdairs
sdairs force-pushed the issue-458-disable-script-telemetry branch from 0c41500 to c4ad7bd Compare August 25, 2026 22:41

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9d275eb. Configure here.

}
if std::net::TcpListener::bind(("127.0.0.1", p)).is_err() {
return Err(Error::PostgresValidation(format!(
return Err(Error::PostgresPortInUse(format!(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Postgres port exhaustion wrong code

Medium Severity

When Postgres auto-selection cannot find a free port, the failure is still raised as PostgresRuntime, so structured mode maps it to local_error with a generic Postgres message. The same exhaustion case for ClickHouse was converted to PortInUse and correctly emits port_in_use, so agents cannot classify this Postgres failure under the documented port code.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9d275eb. Configure here.

@sdairs

sdairs commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #556 in stack #563.

@sdairs sdairs closed this Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Emit structured errors in local --json and agent mode

2 participants