Skip to content

[nightshift] error-msg-improve: error message quality analysis #32

@nightshift-micr

Description

@nightshift-micr

Error Message Quality Report

Repository: Microck/tailstick
Task: error-msg-improve
Date: 2026-04-20

Summary

Severity Count Description
P0 5 User-blocking or security-relevant silent failures
P1 8 Missing error context, debugging-blind spots
P2 14 Bare return err without operation context
P3 4 Quality improvements / nice-to-have

Total findings: 31 (41 bare return err, 21 ignored errors, 12 fmt.Errorf without %w, 5 silent failures)

P0 — Security / User-Blocking

  1. client.go:148 — DeleteDevice returns nil (success) when apiKey/deviceID is empty. Silently skips device deletion, leaving orphaned devices.
  2. workflow.go:334 — json.Unmarshal failure silently ignored during cleanup decryption. Wrong cleanup config = skipped device deletion.
  3. server.go:174 — GUI enroll endpoint returns HTTP 400 for all errors including server-side failures. Leaks internal error messages (file paths, encryption details) to browser.
  4. workflow.go:370 — Audit write failure silently swallowed during cleanup (_ = state.AppendAudit(...)). Loses audit trail.
  5. cli.go:60,115,157 — Flag parse errors exit code 2 with no message. User sees silent exit.

P1 — Debugging-Critical

  1. crypto/secret.go — Encrypt has 7 bare errors with zero context. Decrypt has 10. Impossible to diagnose which step failed.
  2. workflow.go:48-70 — NewManager returns 4 bare errors without context.
  3. workflow.go:718-740 — resolveCleanupFromConfig/resolvePresetFromConfig silently swallow errors and return empty config.
  4. workflow.go:98-190 — Enroll returns 8 bare errors. User only sees "enroll: ".
  5. client.go:89-105 — Tailscale Up/Down/Logout/Status return bare runner errors.
  6. client.go:108-115 — Status JSON parse failure silently falls through to fallback.
  7. client.go:152-158 — DeleteDevice HTTP errors returned without context.

P2 — Quality (41 bare return err)

Key files: workflow.go (18 occurrences), tailscale/client.go (6), state/store.go (6), platform/platform.go (1), logging/logger.go (2).

Most impactful: crypto/secret.go — 18 bare error returns make debugging cryptographic failures impossible.
Most impactful pattern: workflow.go Enroll method — 8 sequential operations all return bare errors.

Recommended Fixes

Immediate (P0)

  • Return errors instead of nil for empty DeleteDevice inputs
  • Handle json.Unmarshal errors during cleanup
  • Distinguish user errors (400) from server errors (500) in GUI
  • Log audit write failures
  • Print flag parse errors + usage on exit

Short-term (P1)

  • Wrap ALL errors in crypto/secret.go with fmt.Errorf("step: %w", err)
  • Wrap NewManager, Enroll errors with operation context
  • Change resolveCleanupFromConfig to return errors instead of empty config

Medium-term (P2)

  • Systematically wrap all bare return err with fmt.Errorf("operation: %w", err)
  • Ensure all fmt.Errorf use %w for error chain preservation

Automated by Nightshift v3 (GLM 5.1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions