Skip to content

Detect empty API keys #378

@MoralCode

Description

@MoralCode

because of the way the composefile is written, "COLLECTOSS_GITHUB_API_KEY=${COLLECTOSS_GITHUB_API_KEY}" can pass an empty value to the application if the environment variable isnt correctly set.

This will cause a cryptic error httpx.LocalProtocolError: Illegal header value b'token ':

Stack Trace
why is this happening?

26-06-10 19:15:17,152: INFO/MainProcess] secondary:50b4f14211634b9da7471cbdd987c837@b3b978ab0f40 ready.
core-1      | [2026-06-10 19:15:17,437: INFO/MainProcess] mingle: all alone
core-1      | [2026-06-10 19:15:17,453: INFO/MainProcess] facade:74395837f5de43b58a101ea04e3aee8f@b3b978ab0f40 ready.
core-1      | [2026-06-10 19:15:17,525: INFO/MainProcess] mingle: sync with 1 nodes
core-1      | [2026-06-10 19:15:17,526: INFO/MainProcess] mingle: sync complete
core-1      | [2026-06-10 19:15:17,539: INFO/MainProcess] core:be7c84aacc704dcd9babdc2342e8b8f7@b3b978ab0f40 ready.
keyman-1    | 2026-06-10 19:15:41,677 - KeyOrchestrator - INFO - ACK; for: 20
keyman-1    | 2026-06-10 19:15:41,677 - KeyOrchestrator - INFO - ACK; for: 20
core-1      | Traceback (most recent call last):
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpcore/_exceptions.py", line 8, in map_exceptions
core-1      |     yield
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpcore/_sync/http11.py", line 114, in _send_request_headers
core-1      |     event = h11.Request(
core-1      |             ^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/h11/_events.py", line 55, in __init__
core-1      |     self.headers = _headers.normalize_and_validate(
core-1      |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/h11/_headers.py", line 131, in normalize_and_validate
core-1      |     validate(_field_value_re, value, "Illegal header value {!r}", value)
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/h11/_util.py", line 88, in validate
core-1      |     raise LocalProtocolError(msg)
core-1      | h11._util.LocalProtocolError: Illegal header value b'token '
core-1      | 
core-1      | During handling of the above exception, another exception occurred:
core-1      | 
core-1      | Traceback (most recent call last):
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpx/_transports/default.py", line 60, in map_httpcore_exceptions
core-1      |     yield
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpx/_transports/default.py", line 218, in handle_request
core-1      |     resp = self._pool.handle_request(req)
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpcore/_sync/connection_pool.py", line 253, in handle_request
core-1      |     raise exc
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpcore/_sync/connection_pool.py", line 237, in handle_request
core-1      |     response = connection.handle_request(request)
core-1      |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpcore/_sync/connection.py", line 90, in handle_request
core-1      |     return self._connection.handle_request(request)
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpcore/_sync/http11.py", line 105, in handle_request
core-1      |     return ctx.invoke(function_db_connection, *args, **kwargs)
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/click/core.py", line 814, in invoke
core-1      |     return callback(*args, **kwargs)
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/click/decorators.py", line 34, in new_func
core-1      |     return f(get_current_context(), *args, **kwargs)
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/collectoss/application/cli/__init__.py", line 115, in new_func
core-1      |     return ctx.invoke(f, *args, **kwargs)
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/click/core.py", line 814, in invoke
core-1      |     return callback(*args, **kwargs)
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/click/decorators.py", line 34, in new_func
core-1      |     return f(get_current_context(), *args, **kwargs)
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/collectoss/application/cli/backend.py", line 158, in start
core-1      |     ghkeyman = GithubApiKeyHandler(logger)
core-1      |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/collectoss/tasks/github/util/github_api_key_handler.py", line 40, in __init__
core-1      |     self.keys = self.get_api_keys()
core-1      |                 ^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/collectoss/tasks/github/util/github_api_key_handler.py", line 119, in get_api_keys
core-1      |     if self.is_bad_api_key(client, key) is False:
core-1      |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/collectoss/tasks/github/util/github_api_key_handler.py", line 161, in is_bad_api_key
core-1      |     data = client.request(method="GET", url=RATE_LIMIT_URL, headers=headers, timeout=180).json()
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpx/_client.py", line 815, in request
core-1      |     return self.send(request, auth=auth, follow_redirects=follow_redirects)
core-1      |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpx/_client.py", line 902, in send
core-1      |     response = self._send_handling_auth(
core-1      |                ^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpx/_client.py", line 930, in _send_handling_auth
core-1      |     response = self._send_handling_redirects(
core-1      |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpx/_client.py", line 967, in _send_handling_redirects
core-1      |     response = self._send_single_request(request)
core-1      |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpx/_client.py", line 1003, in _send_single_request
core-1      |     response = transport.handle_request(request)
core-1      |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpx/_transports/default.py", line 217, in handle_request
core-1      |     with map_httpcore_exceptions():
core-1      |   File "/usr/local/lib/python3.11/contextlib.py", line 158, in __exit__
core-1      |     self.gen.throw(typ, value, traceback)
core-1      |   File "/collectoss/.venv/lib/python3.11/site-packages/httpx/_transports/default.py", line 77, in map_httpcore_exceptions
core-1      |     raise mapped_exc(message) from exc
core-1      | httpx.LocalProtocolError: Illegal header value b'token '

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions