Conversation
A missing LINEAR_API_KEY previously surfaced as a raw
%Ash.Error.Unknown{} dump reaching the generic catch-all handler ("What
the heck is this?" + a full Ash stacktrace) - the Ash manual actions
wrapping LinearCli.Api.call/2's {:error, :missing_api_key} produced a
shape that didn't match either existing specific handle_error/3 clause.
Adds a clause matching that exact wrapped shape (Ash stringifies the
original reason into UnknownError's :error field rather than
preserving the atom - verified directly, not guessed) and prints a
clear, actionable message instead, with sysexits.h's EX_CONFIG (78)
since this is a configuration problem, not a crash. Plain pattern
match, no guard, so it degrades gracefully to the existing catch-all if
Ash's wrapping format ever changes rather than introducing a new
failure mode.
Closes #74.
There was a problem hiding this comment.
Pull request overview
Improves the CLI’s UX when LINEAR_API_KEY is missing by intercepting the specific Ash-wrapped “missing api key” error shape and emitting a clear, actionable configuration message while exiting with EX_CONFIG (78), instead of falling through to the generic “What the heck is this?” handler.
Changes:
- Add a dedicated
handle_error/3clause for the Ash%Ash.Error.Unknown{...}shape produced whenLinearCli.Api.call/2returns{:error, :missing_api_key}. - Print a targeted message (with a settings URL) and exit 78 for missing configuration.
- Add an
async: falseregression test that unsets/restoresLINEAR_API_KEYand asserts on stderr output + exit code.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| app/lib/linear_cli/cli.ex | Adds a specific error handler for the “missing API key” Ash error wrapper and exits with 78 + friendly guidance. |
| app/test/linear_cli/cli/missing_api_key_test.exs | Adds a non-async test ensuring the CLI prints the friendly message and exits 78 when LINEAR_API_KEY is unset. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This was referenced Aug 12, 2026
bougyman
pushed a commit
that referenced
this pull request
Aug 12, 2026
🤖 I have created a release *beep* *boop* --- ## [1.2.0](v1.1.1...v1.2.0) (2026-08-12) ### Features * add a root-level repo-management Mix project (mix container.build/publish) ([#84](#84)) ([9d0b730](9d0b730)) ### Bug Fixes * give a clear message and exit 78 when LINEAR_API_KEY is missing ([#86](#86)) ([c5b9ec1](c5b9ec1)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #74. A missing
LINEAR_API_KEYpreviously surfaced as a raw%Ash.Error.Unknown{}dump reaching the generic catch-all handler ("What the heck is this?" + a full Ash stacktrace) - the Ash manual actions wrappingLinearCli.Api.call/2's{:error, :missing_api_key}produced a shape that didn't match either existing specifichandle_error/3clause.Adds a clause matching that exact wrapped shape (Ash stringifies the original reason into
UnknownError's:errorfield rather than preserving the atom - verified directly, not guessed) and prints a clear, actionable message instead, with sysexits.h'sEX_CONFIG(78) since this is a configuration problem, not a crash. Plain pattern match, no guard, so it degrades gracefully to the existing catch-all if Ash's wrapping format ever changes rather than introducing a new failure mode.Test plan
env -u LINEAR_API_KEY mix run -e 'LinearCli.CLI.main(["issue", "list"])') before fixing, confirmed the fix resolves it aftermissing_api_key_test.exs,async: falsemirroringLinearCli.ApiTest's existing env-var-unset pattern) - clear message, exit 78, no raw Ash dumpmix test- no regressions (14 pre-existing GPG/pinentry sandbox failures reproduce identically on a clean stash of this branch, unrelated)mix format --check-formattedclean🤖 Generated with Claude Code