Skip to content

Ignore empty GitHub API keys - #484

Open
drkrillo wants to merge 2 commits into
chaoss:mainfrom
drkrillo:fix/empty-api-keys-378
Open

drkrillo wants to merge 2 commits into
chaoss:mainfrom
drkrillo:fix/empty-api-keys-378

Conversation

@drkrillo

Copy link
Copy Markdown

Description

When COLLECTOSS_GITHUB_API_KEY env variable was set to one or more whitespaces or left empty, that counted as set config_key, causing httpx.LocalProtocolError: Illegal header value b'token '.

Now, in GithubApiKeyHandler.get_api_keys():

  • If the key is set to one or more whitespaces or left empty, a warning is logged and the code doesn't add it to the keys list (new cases).
  • If its None, the warning is not logged and doesn't add the key (already covered before the fix).

Added tests/test_classes/test_github_api_keys.py covering the config key cases:
empty and whitespaces with and without database keys, None, and a valid key. Each one
asserts the key list, if the key is probed, and the warning.

docker compose up --build logs after the fix:

core-1      | 2026-09-16 23:41:45 097a6abde2c1 collectoss[33] WARNING GitHub API key is an empty string. Please, add a valid one.
core-1      | 2026-09-16 23:41:45 097a6abde2c1 collectoss[33] INFO Retrieved 0 github api keys for use

This PR fixes #378

Notes for Reviewers

  • The same issue is present in GitlabApiKeyHandler.get_api_keys(). I didn't add that fix here, just GitHub's. Let me know if I can open up a follow-up PR, open an issue (or both) or add the code and tests in this same PR.

Signed commits

  • Yes, I signed my commits.

Generative AI disclosure

Please select one option:

  • This contribution was NOT assisted or created by Generative AI tools.
  • This contribution was assisted or created by Generative AI tools.

If AI tools were used, please provide details below:
- What tools were used? Claude
- How were these tools used? Code review and tests guidance (not writing, suggested new ones covering cases I didn't consider)
- Did you review these outputs before submitting this PR? Yes, all the code was written by me, trying different approaches and Claude was used to review the changes.

Signed-off-by: Juan Pasutti <juanpasutti@gmail.com>
@drkrillo
drkrillo requested a review from MoralCode as a code owner September 17, 2026 01:19

@MoralCode MoralCode left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution and welcome to CHAOSS (i see this is your first contribution)! Had some questions about the code

Comment on lines -105 to +109
if self.config_key is not None:
keys += [self.config_key]
if self.config_key is not None: # Leave out None values
if self.config_key.strip(): # Leave out empty strings
keys += [self.config_key]
else:
self.logger.warning("GitHub API key is an empty string. Please, add a valid one.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm i wonder if we could shorten this to

if self.config_key:
(and keep the else block)

AFAIK (needs testing) i think python treats empty strings as falsy

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this approach before the actual nested implementation. The three cases are pinned in the test file ("", " ", None)

The problem is that if self.config_key: would catch None and "", but " " is not falsy, so it gets added . With a flat else, None logs the warning, which test_none_config_key_with_no_db_keys asserts it shouldn't: None just means the variable was never set.

Also tried if self.config_key.strip(). Catches de whitespace but raises an AttributeError on None.


assert handler.keys == [github_valid_api_key]
assert probe.call_count == 1
logger.warning.assert_not_called()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this logger.warning.assert_not_called() syntax looks really weird to me. i would expect a logging call to look like logger.warning("message") and an assertion to be assert something.assert_not_called()

oh wait now that i think about it, youre trying to assert that no warnings were logged in the original function.

is there a way we can assert on something more robust in addition to the logging check? (like to see whether self.redis_key_list gets added to or not? or factor some amount of this into a function that can be independently tested?)

Asserting unit tests based on whether warnings are logged seems a bit fragile but i guess if there's no better way its probably okay.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, added the redis_key_list assert. Each test now checks the state: with no keys left get_api_keys returns before it reaches redis, so clear and extend never get called, and with a valid key extend is called once with that key. The warning is still checked (secondary one now)

Two other small things in that push: renamed probe to mock_is_bad_api_key, and test 4 was comparing against the same list that keys += [...] mutates, so now it compares against a fixed value and gets a copy.

Signed-off-by: Juan Pasutti <juanpasutti@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Detect empty API keys

2 participants