Skip to content

[nightshift] Error Message Improvements #25

@nightshift-micr

Description

@nightshift-micr

Error Message Improvement Report — tailstick

Repository: Microck/tailstick
Files analyzed: 16 Go source files (12 non-test, 4 test)
Date: 2026-04-18


Severity Definitions

Level Meaning
P0 Error swallows underlying cause entirely (no %w wrapping) — impossible to diagnose programmatically
P1 Error message is vague, lacks context, or is misleading — user/admin cannot act on it
P2 Error is adequately wrapped but message could be more specific/actionable
P3 Minor wording improvement; nice-to-have

P0 — Errors That Swallow Underlying Causes (17 locations)

1. crypto/secret.go — Entire Encrypt and Decrypt functions pass through bare errors

Lines: 31, 34, 37, 43, 54, 60, 64, 68, 72, 76, 81, 84, 87, 92, 101, 110, 125

Every error in Encrypt() and Decrypt() is returned as raw err with no wrapping. When encryption/decryption fails, the caller gets a bare cipher: message authentication failed with zero indication it came from the crypto package.

Fix: Wrap all errors with fmt.Errorf("operation description: %w", err).

2. state/store.goSave() returns bare errors (lines 42, 46, 50, 52)

os.MkdirAll, json.MarshalIndent, os.WriteFile, os.Rename all return bare errors.

3. state/store.goAppendAudit() returns bare errors (lines 68, 73, 78, 81)

Same pattern — all audit file operations return bare errors.

4. logging/logger.goNew() returns bare errors (lines 23, 27)

5. platform/platform.goEnsureParent() returns bare error (line 91)

6. app/workflow.go — Multiple bare error returns in Enroll() (lines 98, 102, 148, 153, 157, 186, 190, 207)

7. app/workflow.goAgentOnce(), AgentRun(), ForceCleanup() (lines 217, 242, 268, 289, 302)

8. tailscale/client.godeleteDevice() returns bare errors for HTTP (lines 153, 158)


P1 — Vague or Missing Context (13 locations)

Key examples:

  • crypto/secret.go line 120"empty key material" → should explain both password and machineContext are empty
  • tailscale/client.go line 64"missing auth key" → should explain where to set it
  • tailscale/client.go line 59"session mode requires ephemeral auth key" → should say which config field
  • tailscale/client.go line 45"stable channel requires configured stable version" → should say where to pin version
  • app/workflow.go line 106"operator password is invalid" → should explain CLI flags/env vars
  • app/workflow.go line 635"preset %s does not allow exit node selection" → should say allowExitNodeSelection=true
  • platform/platform.go lines 146, 152 — Linux distro messages give no guidance

P2 — Wrapped but Could Be More Specific (8 locations)

  • config/config.go lines 28, 35 — missing file path in error
  • tailscale/client.go line 169 — missing device ID for correlation
  • gui/server.go line 71 — port validation could suggest using 0
  • gui/server.go line 139 — "invalid json body" doesn't include parse error

P3 — Minor Wording (7 locations)

Various config validation and CLI error messages could be more specific.


Summary

Severity Count Description
P0 17 locations Bare errors with no wrapping
P1 13 locations Vague or missing context
P2 8 locations Could be more specific
P3 7 locations Minor wording
Total 45 findings Across 8 source files

Key Patterns

  1. crypto/secret.go has 15 bare error returns — worst offender, fix first
  2. state/store.go has 6 bare errors — state persistence loses diagnostic context
  3. app/workflow.go has ~20 bare errors scattered through enrollment, agent, and cleanup flows
  4. No errors use errors.Is()/errors.As() sentinel patterns

Generated 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