Detail Bug Report
https://app.detail.dev/org_5f375fe3-a706-4e9a-a6f7-800f2439b3f6/bugs/bug_e0844d3e-9426-41a9-97a0-50c10d41af55
Introduced in #129 by @sachiniyer on Mar 6, 2026
Summary
- Context: The CLI handles all command errors through
src/main.rs which formats them before display.
- Bug: Using
{err} format hides the entire error chain, removing essential debugging information (HTTP status codes) that users need to take corrective action.
- Actual vs. expected: Users see "Failed to fetch repositories" but cannot tell if it's an authentication failure (401), permission issue (403), or not found (404).
- Impact: Users must guess which diagnostic command to run.
Code with Bug
// src/main.rs:13
let _ = Term::stderr().write_line(&format!("Error: {err}")); // <-- BUG 🔴 Display formatting drops the error chain
Explanation
anyhow error chains typically contain the actionable root cause (e.g., "401 Unauthorized"). Printing errors with Display ({err}) only shows the top-level context message (e.g., "Failed to fetch repositories") and discards the Caused by: chain.
This is observable in the current chain construction:
- Command adds a generic context (
.context("Failed to fetch repositories")).
- API client wraps an underlying HTTP error (
anyhow!("API error: {e}")) that includes status/message.
src/main.rs prints only the top-level Display string, so users never see the HTTP status.
As a result, the same 401 condition can yield helpful guidance in detail auth login --token ... but only "Failed to fetch repositories" in detail repos list, forcing users to guess to run detail auth status.
Codebase Inconsistency
Real CLI output shows inconsistent guidance for the same auth failure:
detail auth login --token <bad>: "Failed to authenticate. Please check your token."
detail repos list with an invalid/expired stored token: "Failed to fetch repositories" (no indication it is auth-related).
Failing Test
// tests/integration.rs
#[test]
fn error_includes_status_code_for_auth_failures() {
let env = Env::new("error_status_code");
env.write_config(r#"api_token = "dtl_live_invalid_token""#);
let out = env.run(&["repos", "list"]);
assert!(!out.success);
assert!(
out.stderr.contains("401") || out.stderr.contains("Unauthorized"),
"Error should indicate auth failure:\nstderr: {}", out.stderr
);
}
Recommended Fix
Preserve the intent to avoid dumping verbose headers/structs, but still surface essential HTTP status/message. One approach is in src/api/client.rs: map the progenitor error into a concise message like 401 Unauthorized: <message> (without headers/struct dumps), so the chain contains actionable information even when top-level errors add context.
History
This bug was introduced in commit 92044b7. The commit aimed to fix verbose error output by switching from anyhow's default Debug formatting to Display formatting ({err} instead of {err:?}), but overcorrected by hiding the entire error chain—including essential diagnostic information like HTTP status codes—rather than just the verbose HTTP headers and struct dumps.
Detail Bug Report
https://app.detail.dev/org_5f375fe3-a706-4e9a-a6f7-800f2439b3f6/bugs/bug_e0844d3e-9426-41a9-97a0-50c10d41af55
Introduced in #129 by @sachiniyer on Mar 6, 2026
Summary
src/main.rswhich formats them before display.{err}format hides the entire error chain, removing essential debugging information (HTTP status codes) that users need to take corrective action.Code with Bug
Explanation
anyhowerror chains typically contain the actionable root cause (e.g., "401 Unauthorized"). Printing errors with Display ({err}) only shows the top-level context message (e.g., "Failed to fetch repositories") and discards theCaused by:chain.This is observable in the current chain construction:
.context("Failed to fetch repositories")).anyhow!("API error: {e}")) that includes status/message.src/main.rsprints only the top-level Display string, so users never see the HTTP status.As a result, the same 401 condition can yield helpful guidance in
detail auth login --token ...but only "Failed to fetch repositories" indetail repos list, forcing users to guess to rundetail auth status.Codebase Inconsistency
Real CLI output shows inconsistent guidance for the same auth failure:
detail auth login --token <bad>: "Failed to authenticate. Please check your token."detail repos listwith an invalid/expired stored token: "Failed to fetch repositories" (no indication it is auth-related).Failing Test
Recommended Fix
Preserve the intent to avoid dumping verbose headers/structs, but still surface essential HTTP status/message. One approach is in
src/api/client.rs: map the progenitor error into a concise message like401 Unauthorized: <message>(without headers/struct dumps), so the chain contains actionable information even when top-level errors add context.History
This bug was introduced in commit 92044b7. The commit aimed to fix verbose error output by switching from anyhow's default Debug formatting to Display formatting (
{err}instead of{err:?}), but overcorrected by hiding the entire error chain—including essential diagnostic information like HTTP status codes—rather than just the verbose HTTP headers and struct dumps.