Summary
LightningWeb.RunChannel.handle_credential_error/5 (lib/lightning_web/channels/run_channel.ex:482-552) pattern-matches a fixed set of error tags but has no catch-all clause. An unexpected error term raises FunctionClauseError, which crashes the run channel during fetch:credential instead of returning a clean {:error, ...} reply to the worker.
Handled cases
The function only has clauses for these five tags:
:environment_not_configured
:project_not_found
:environment_mismatch
:reauthorization_required
:temporary_failure
The unhandled case
Lightning.Credentials.Resolver.resolve_credential/2 can return an open-ended error shape that none of those clauses match.
In lib/lightning/credentials.ex:1205-1213, when an OAuth token refresh fails with anything other than:
invalid_grant / HTTP 400-401 → mapped to :reauthorization_required
- HTTP 429-503 → mapped to
:temporary_failure
…it falls through to a raw pass-through:
{:error, error} ->
# audit ...
{:error, error} # raw, untyped error term
That raw error is wrapped by the resolver (lib/lightning/credentials/resolver.ex:114) into {:error, {error, credential}} and handed to handle_credential_error/5 as the error tuple. The first element is then an arbitrary term — e.g. %{status: 500}, :timeout, a Mint.TransportError, connection-refused, etc.
Since none of the five clauses match and there is no fallback clause, this raises FunctionClauseError and crashes the channel.
Impact
Any OAuth-provider failure that is not a 429/503 or an auth-revocation — most notably 5xx responses, network/transport errors, and timeouts — crashes the run channel mid-fetch:credential. The worker loses the connection rather than receiving a clean error reply.
Code references
lib/lightning_web/channels/run_channel.ex:482-552 — handle_credential_error/5 clauses
lib/lightning_web/channels/run_channel.ex:154-155 — call site forwarding {:error, error_tuple}
lib/lightning/credentials/resolver.ex:114 — wraps reason into {reason, credential}
lib/lightning/credentials.ex:1205-1213 — raw pass-through of unknown OAuth refresh errors
Note on a non-issue
The resolver's %Credential{} clause can surface a raw :environment_not_found (resolver.ex:99), but this channel only ever calls resolve_credential(run, id) with a %Run{} (run_channel.ex:144). On the %Run{} path that tag is remapped to :environment_mismatch (resolver.ex:110), so it never reaches handle_credential_error/5 here.
Summary
LightningWeb.RunChannel.handle_credential_error/5(lib/lightning_web/channels/run_channel.ex:482-552) pattern-matches a fixed set of error tags but has no catch-all clause. An unexpected error term raisesFunctionClauseError, which crashes the run channel duringfetch:credentialinstead of returning a clean{:error, ...}reply to the worker.Handled cases
The function only has clauses for these five tags:
:environment_not_configured:project_not_found:environment_mismatch:reauthorization_required:temporary_failureThe unhandled case
Lightning.Credentials.Resolver.resolve_credential/2can return an open-ended error shape that none of those clauses match.In
lib/lightning/credentials.ex:1205-1213, when an OAuth token refresh fails with anything other than:invalid_grant/ HTTP 400-401 → mapped to:reauthorization_required:temporary_failure…it falls through to a raw pass-through:
That raw
erroris wrapped by the resolver (lib/lightning/credentials/resolver.ex:114) into{:error, {error, credential}}and handed tohandle_credential_error/5as the error tuple. The first element is then an arbitrary term — e.g.%{status: 500},:timeout, aMint.TransportError, connection-refused, etc.Since none of the five clauses match and there is no fallback clause, this raises
FunctionClauseErrorand crashes the channel.Impact
Any OAuth-provider failure that is not a 429/503 or an auth-revocation — most notably 5xx responses, network/transport errors, and timeouts — crashes the run channel mid-
fetch:credential. The worker loses the connection rather than receiving a clean error reply.Code references
lib/lightning_web/channels/run_channel.ex:482-552—handle_credential_error/5clauseslib/lightning_web/channels/run_channel.ex:154-155— call site forwarding{:error, error_tuple}lib/lightning/credentials/resolver.ex:114— wraps reason into{reason, credential}lib/lightning/credentials.ex:1205-1213— raw pass-through of unknown OAuth refresh errorsNote on a non-issue
The resolver's
%Credential{}clause can surface a raw:environment_not_found(resolver.ex:99), but this channel only ever callsresolve_credential(run, id)with a%Run{}(run_channel.ex:144). On the%Run{}path that tag is remapped to:environment_mismatch(resolver.ex:110), so it never reacheshandle_credential_error/5here.