Example: This code

class {:autocontracts} A {
    ghost predicate Valid() {
        true
    }

    constructor() {
        // no-op
    }
}

class {:autocontracts} B {
    var things: set<A>

    ghost predicate Valid()
        reads things
    {
        forall thing | thing in things :: thing.Valid()
    }

    constructor() {
        things := {};
    }
}

produces this output:

ERROR_InsufficientReads.dfy(17,48): Error: insufficient reads clause to invoke function

Dafny program verifier finished with 3 verified, 1 error

This error message indicates that a nested call of a function needs a bigger reads set than its enclosing function provides.

Another situation provoking this error is this:

class A {
  var x: int
  predicate IsSpecial() reads this {
    x == 2
  }
}
type Ap  = x : A | x.IsSpecial() witness *

In this case the error message is a bit misleading. The real problem is that the predicate in the subset declaration (that is, x.IsSpecial()) is not allowed to depend on the heap, as IsSpecial does. If such a dependency were allowed, then changing some values in the heap could possibly change the predicate such that a value which was allowed in the subset type now suddenly is not. This situation would be a disaster for both soundness and ease of reasoning.

Another variation on the above is this example:

trait A { var x: int }
type AZero = a: A | a.x == 0 witness *

where again the predicate depends on a heap variable x, which Dafny does not permit.

And a final example:

datatype Foo = Foo | Foofoo

class Bar {
  var foo: set<Foo>;
  function method getFoo(): set<Foo> { this.foo }
}

which produces Error: insufficient reads clause to read field. In this case the function getFoo does indeed have an insufficient reads clause, as it does not have one, yet it reads a field of this. You can insert either reads this or reads this`foo before the left brace.

The code in the original question is fixed like this:

class A {
    predicate Valid() reads this {
        true
    }

    constructor() {
        // no-op
    }
}

class B {
    var things: set<A>

    predicate Valid()
        reads this, things
    {
        forall thing | thing in things :: thing.Valid()
    }

    constructor() {
        things := {};
    }
}