code: func (bk *Backend) GetVal(bucket []string, key string) ([]byte, error) {
  	// Open the bucket to work on the items.
  	b, err := bk.openBucket(bk.flatten(bucket), os.O_RDWR)
  	if err != nil {
  		// GetVal on a bucket needs to return trace.BadParameter. If opening the
  		// bucket failed a partial match up to a bucket may still exist. To support
  		// returning trace.BadParameter in this situation, loop over all keys in the
  		// backend and see if any match the prefix. If any match the prefix return
  		// trace.BadParameter, otherwise return the original error. This is
  		// consistent with our DynamoDB implementation.
  		files, er := ioutil.ReadDir(path.Join(bk.rootDir))
  		if er != nil {
  			return nil, trace.ConvertSystemError(er)
  		}
  		var matched int
  		for _, fi := range files {
  			pathToBucket := bk.pathToBucket(fi.Name())
  			fullBucket := append(bucket, key)
  			bucketPrefix := bk.flatten(fullBucket)
  
  			// Prefix matched, for example if pathToBucket is "/foo/bar/baz" and
  			// bucketPrefix is "/foo/bar".
  			if strings.HasPrefix(pathToBucket, bucketPrefix) {
  				matched = matched + 1
  			}
  		}
  		if matched > 0 {
  			return nil, trace.BadParameter("%v is not a valid key", key)
  		}
  		return nil, trace.ConvertSystemError(err)
  	}
  	defer b.Close()
  
  	// If the key does not exist, return trace.NotFound right away.
  	item, ok := b.getItem(key)
  	if !ok {
  		return nil, trace.NotFound("key %q is not found", key)
  	}
  
  	// If the key is expired, remove it from the bucket and write it out and exit.
  	if bk.isExpired(item) {
  		b.deleteItem(key)
  
  		return nil, trace.NotFound("key %q is not found", key)
  	}
  
  	return item.Value, nil
  }
docs: // GetVal return a value for a given key in the bucket