Skip to content

RunChannel.handle_credential_error/5 has no fallback clause for unexpected OAuth errors #4853

Description

@midigofrank

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-552handle_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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugNewly identified bugneeds investigationbug identified, needs replication and investigation

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions