Skip to content

fix(cli): warn when the stored client config cannot be read - #312

Open
KrasimirKralev wants to merge 1 commit into
openclaw:mainfrom
KrasimirKralev:fix/client-config-unreadable-warning
Open

KrasimirKralev wants to merge 1 commit into
openclaw:mainfrom
KrasimirKralev:fix/client-config-unreadable-warning

Conversation

@KrasimirKralev

Copy link
Copy Markdown
Contributor

What Problem This Solves

When the stored client config file is damaged or unreadable, every client command silently ignores it and talks to http://localhost:8080 with no token, so a logged-in user sees connection refused (or a bare 401 from a local server) with nothing pointing at the file.

  • Problem: defaultClientOptions() (apps/api/cmd/clickclack/client.go:108) drops every loadClientConfig() error, not only "file does not exist". A truncated config.json (interrupted editor save, full disk) or one the user cannot read looks exactly like "never logged in".
  • What did NOT change: the fallback itself, exit codes, stdout, --json output, and the missing-file case (still silent). No config format or path change; login/logout behave as before.
  • Requested by a maintainer? No, found while reading the client config path.

User Impact

A user whose config is damaged now gets one stderr line naming the file, the parse or open error, and the way out (clickclack login or delete the file), instead of a network error about a server they never configured.

Why This Change Was Made

  • What changed: defaultClientOptions() prints a one-line stderr warning when loadClientConfig() fails with anything other than os.ErrNotExist; loadClientConfig() wraps JSON errors with the file path (read errors from os.ReadFile already carry it). One ## Unreleased CHANGELOG line.
  • Root cause: if err == nil { … } with no else branch treated every error as "no config".
  • Missing detection / guardrail: nothing covered the unreadable-config path. New client_config_test.go: a truncated config must produce the warning naming the path and keep the built-in default server; a missing config and a valid config must stay quiet. With the client.go change reverted the truncated-config case fails and the two quiet cases still pass; gofmt, go vet ./cmd/clickclack and go test ./... in apps/api pass.

Evidence

  • Behavior or issue addressed: what clickclack whoami prints after a successful login when the stored config.json is then truncated.
  • Real environment tested: Linux, go build ./cmd/clickclack of upstream/main (fb9b931) and of this branch (36337e1); a scratch clickclack serve --dev-bootstrap on 127.0.0.1:18432 with a magic link from clickclack admin magic-link create; HOME and XDG_CONFIG_HOME under a scratch dir.
  • Exact steps or command run after this patch: clickclack login --server http://127.0.0.1:18432 --magic-token mgt_…, clickclack whoami, truncate -s 40 on the stored config, then clickclack whoami with each binary; plus a mode-000 config and the no-config / valid-config controls.
  • Evidence after fix:
$ clickclack login --server http://127.0.0.1:18432 --magic-token mgt_…
logged in as Proof
exit 0
$ clickclack whoami
usr_01m6dw2qgfg5macxgvwjwhxr15	Proof
exit 0
$ truncate -s 40 "$XDG_CONFIG_HOME/clickclack/config.json"
# --- before: upstream/main fb9b9314
$ clickclack whoami
2026/11/02 12:15:03 Get "http://localhost:8080/api/me": dial tcp 127.0.0.1:8080: connect: connection refused
exit 1
# --- after: this branch 36337e1d
$ clickclack whoami
clickclack: ignoring stored client config: parse <scratch>/home/.config/clickclack/config.json: unexpected end of JSON input (run "clickclack login" to replace it, or delete the file)
2026/11/02 12:15:03 Get "http://localhost:8080/api/me": dial tcp 127.0.0.1:8080: connect: connection refused
exit 1

## config with mode 000
$ clickclack whoami   # before
2026/11/02 12:14:31 Get "http://localhost:8080/api/me": dial tcp 127.0.0.1:8080: connect: connection refused
exit=1
$ clickclack whoami   # after
clickclack: ignoring stored client config: open <scratch>/home/.config/clickclack/config.json: permission denied (run "clickclack login" to replace it, or delete the file)
2026/11/02 12:14:31 Get "http://localhost:8080/api/me": dial tcp 127.0.0.1:8080: connect: connection refused
exit=1

## controls, identical before and after
$ clickclack whoami   # no config file
2026/11/02 12:14:31 Get "http://localhost:8080/api/me": dial tcp 127.0.0.1:8080: connect: connection refused
exit=1
$ clickclack whoami   # valid config {"server":"http://127.0.0.1:9"}
2026/11/02 12:14:31 Get "http://127.0.0.1:9/api/me": dial tcp 127.0.0.1:9: connect: connection refused
exit=1
  • Observed result after fix: running the clickclack binary, a truncated or unreadable config now prints one stderr line with the path, the error and the fix; the request and exit code are unchanged. Without a config file, and with a valid one, the output is identical on both binaries.
  • What was not tested: macOS and Windows config locations (the path comes from os.UserConfigDir(), unchanged here).
  • Proof limitations or environment constraints: none beyond the scratch server and scratch config dir.

@KrasimirKralev
KrasimirKralev requested a review from a team as a code owner November 2, 2026 10:15
@clawsweeper

clawsweeper Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. labels Nov 2, 2026
@clawsweeper

clawsweeper Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

What this changes

This PR warns on stderr when stored client configuration cannot be read or parsed and includes the file path in JSON parse errors.

Example: After login to http://127.0.0.1:18432, config.json is truncated and the user runs clickclack whoami.

  • Before: The command reports a connection failure against http://localhost:8080 without explaining why the saved server was ignored.
  • After: A warning first identifies the damaged config file and suggests login or file removal; the existing request and exit status remain unchanged.

Review scores

Measure Result What it means
Overall readiness 🦞 diamond lobster (5/6) A narrow, useful diagnostic fix with shipped CLI proof, meaningful regression coverage, and no identified correctness or compatibility defect; source comparison verifies no persisted-format migration is needed.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (terminal): The contributor's Linux terminal trace exercises the built clickclack whoami entry point after login, showing the new path-bearing warning for truncated and unreadable configs while missing and valid config controls retain their prior behavior.
Patch quality 🦞 diamond lobster (5/6) No actionable review findings were identified.

Product

Kind: Bug fix · Worth it: Yes · Fix scope: Complete
User problem: A damaged saved config makes client commands report an unrelated localhost failure without identifying the ignored file.
Reason: An actionable stderr diagnostic has clear value and preserves the established optional-config and server-scoping contracts.

Merge readiness

✅ Ready for maintainer review

Keep this PR open: current main still silently discards config-read errors, and this focused diagnostic fix has no actionable findings.

Priority: P2
Reviewed head: 36337e1d300962a5670a24918f00468ed2cd07a6

Before merge

None.

Findings

None.

Agent review details

How this fits together

The CLI loads saved server and credential defaults before dispatching client commands; configuration errors now produce stderr diagnostics while existing option precedence and HTTP requests remain unchanged.

flowchart TD
A[CLI arguments and environment] --> B[Client defaults]
C[Stored config file] --> D[Config loader]
D --> B
D --> E[Stderr warning on read or parse failure]
B --> F[Client command]
F --> G[HTTP API]
Loading

Technical review

Best possible solution:

Land the focused warning and path-aware parse error while preserving existing fallback and credential-storage behavior.

Do we have a high-confidence way to reproduce the issue?

Current-main source demonstrably drops non-missing-file loading errors, and the contributor supplies matching before/after CLI traces; no target code was executed during this review.

Is this the best way to solve the issue?

The existing shared loader is the appropriate owner, and the patch adds the missing diagnostic without introducing another configuration path or changing fallback semantics.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against fb9b9314bdfe.

Provenance checked

  • Optional stored client configuration loading changes intended behavior with a stated reason (a9f86a2: The original CLI feature established optional saved defaults and fallback behavior; no requirement to hide malformed-file errors was found.)

Testing

Proof path: shipped entry point.

Security

None.

Evidence

What I checked:

Likely related people:

  • Peter Steinberger: Raw commit a9f86a2 adds apps/api/cmd/clickclack/client.go:94 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: a9f86a21f24c; files: apps/api/cmd/clickclack/client.go)

Review metrics

Metric Value Why it matters
Patch scope Production +7/-1 lines; tests +75; changelog +1 The small production change is supported by distinct corrupt, missing, and valid configuration cases.

Labels

Label changes:

  • add P2: This fixes misleading CLI diagnostics for damaged or unreadable saved configuration without changing request behavior.
  • add proof: sufficient: Contributor real behavior proof is sufficient.
  • add rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR.

Label justifications:

  • P2: This fixes misleading CLI diagnostics for damaged or unreadable saved configuration without changing request behavior.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR.
  • proof: sufficient: Contributor real behavior proof is sufficient.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

Reviewed November 2, 2026, 5:28 AM ET / 10:28 UTC.

This branch has not been deployed

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

Labels

P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant