Skip to content

Don't return the root of a CoT twice when it's also a link#787

Merged
Eijebong merged 1 commit intomozilla-releng:mainfrom
Eijebong:fix-cot-verify-duped-root
Apr 9, 2026
Merged

Don't return the root of a CoT twice when it's also a link#787
Eijebong merged 1 commit intomozilla-releng:mainfrom
Eijebong:fix-cot-verify-duped-root

Conversation

@Eijebong
Copy link
Copy Markdown
Contributor

@Eijebong Eijebong commented Apr 9, 2026

Creating the CoT here, with no_check_task being default (False)

cot = ChainOfTrust(context, opts.task_type, task_id=opts.task_id)
check_task = opts.no_check_task is False
await verify_chain_of_trust(cot, check_task=check_task)

Then because check_task is true, it calls build_link with itself, adding a LinkOfTrust with the same task ID.

if check_task:
await build_link(chain, chain.name, chain.task_id)

Then we call verify_task_types on that chain, which calls get_all_links_in_chain and actually verifies links. That's where the log is coming from.

for obj in chain.get_all_links_in_chain():
task_type = obj.task_type
log.info("Verifying {} {} as a {} task...".format(obj.name, obj.task_id, task_type))
task_count.setdefault(task_type, 0)
task_count[task_type] += 1
# Run tests synchronously for now. We can parallelize if efficiency
# is more important than a single simple logfile.
await valid_task_types[task_type](chain, obj)

The problem is that get_all_links_in_chain returns [self] + self.links if the CoT object isn't a decision task

def get_all_links_in_chain(self):

So it ends up returning the root task twice, one because of [self] and once because check_task added the root as a LoT to the CoT.


get_all_links_in_chain was added in
0356bbb but at the time, check_task didn't exist so it was correct. The bug was introduced by 8b6ab79 which started adding the root of a CoT as a link, making get_all_links_in_chain return "dupes" for it.

This most likely never got caught because it only happens when check_task is True which isn't the case for scriptworkers, only verify_cot and only when checking a non decision task.

This fixes the issue by not relying on the task type to know whether or not it should return itself in the chain but by looking down the graph to see if it's already included or not.

Copy link
Copy Markdown
Contributor

@bhearsum bhearsum left a comment

Choose a reason for hiding this comment

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

Thanks for the sleuthing and the fix!

@Eijebong Eijebong enabled auto-merge (squash) April 9, 2026 13:14
Creating the CoT here, with `no_check_task` being default (False)
https://github.com/mozilla-releng/scriptworker/blob/6b0b66b03e9ec07b462a550b19b742a863d6b17a/src/scriptworker/cot/verify.py#L2089-L2091

Then because `check_task` is true, it calls `build_link` with itself,
adding a `LinkOfTrust` with the same task ID.
https://github.com/mozilla-releng/scriptworker/blob/6b0b66b03e9ec07b462a550b19b742a863d6b17a/src/scriptworker/cot/verify.py#L2044-L2045

Then we call `verify_task_types` on that chain, which calls
`get_all_links_in_chain` and actually verifies links. That's where the
log is coming from.
https://github.com/mozilla-releng/scriptworker/blob/6b0b66b03e9ec07b462a550b19b742a863d6b17a/src/scriptworker/cot/verify.py#L1806-L1813

The problem is that `get_all_links_in_chain` returns `[self] +
self.links` if the `CoT` object isn't a decision task
https://github.com/mozilla-releng/scriptworker/blob/6b0b66b03e9ec07b462a550b19b742a863d6b17a/src/scriptworker/cot/verify.py#L212

So it ends up returning the root task twice, one because of `[self]` and
once because `check_task` added the root as a `LoT` to the `CoT`.

---

`get_all_links_in_chain` was added in
0356bbb but at the time, `check_task`
didn't exist so it was correct. The bug was introduced by
8b6ab79 which started adding the root
of a `CoT` as a link, making `get_all_links_in_chain` return "dupes" for
it.

This most likely never got caught because it only happens when
check_task is True which isn't the case for scriptworkers, only
`verify_cot` and only when checking a non decision task.

This fixes the issue by not relying on the task type to know whether or
not it should return itself in the chain but by looking down the graph
to see if it's already included or not.
@Eijebong Eijebong force-pushed the fix-cot-verify-duped-root branch from 1ecf564 to f3c0f29 Compare April 9, 2026 13:14
@Eijebong Eijebong merged commit 4e38f5d into mozilla-releng:main Apr 9, 2026
12 checks passed
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.

2 participants