Why do Dagger components have to declare their scope?

Because scopes by themselves don't mean anything. It's the components and their relationships that introduce meaning to scopes.

Unscoped objects can be provided from any component if their dependencies are available. Since they are unscoped there will be a new object created every time that you call their provider. A scoped object will share the lifecycle of the component of the same scope and it will only ever be created once per component. If you recreate the component, you recreate all the objects within its scope. This is where things would get tricky.

Say you have the following setup: a component, and a subcomponent, as it is often the case.

@Component interface MyComponent {}

@Subcomponent interface MySubComponent {}

Now let's say we have two classes, Foo in @FooScope and Bar in @BarScope. Both support constructor injection and both have the scope annotation on their respective class. Let's say we add a provision method for the two to our subcomponent:

interface MySubComponent {

  Foo getFoo();

  Bar getBar();

Now the big question: Where do Foo or Bar get created and which component's "lifecycle" do they share?

We do know that Foo and Bar are in different scopes but that's about it. If one depends on the other we may be able to deduce that one resides in the (parent) component and the other in the subcomponent since one can only ever depend on objects of the same or a higher scope, but this will only ever work for this simple setup and will leave us with uncertainty again if we ever decide to add a third component to this setup.

What happens if we have 3 scopes, but only two components? Which of the two components should host two scopes (if that even makes sense)? Or if it were to report an error, which scope is "the wrong one"? There would simply be no way of knowing for sure.

Those problems will disappear if you also add a scope to the component. It will now be clear which component handles which (scoped) objects, and it is easy enough to report errors when there are unknown scopes introduced.