Deploy fails with "package main must be the top-level package" error / App Engine Standard supports user defined func main()

1,122 views
Skip to first unread message

Adam Tanner

unread,
Oct 20, 2016, 9:36:36 PM10/20/16
to google-appengine-go
Hiya Gophers!

I've gotten a few questions about the error "package main must be the top-level package" that some users are encountering in their deploys so I figured I'd go ahead and post here.

This stems from a new feature we're rolling out with this release that allows App Engine Standard Go applications to respect func main() in package main to bring App Engine Standard applications more in line with App Engine Flex and the rest of the Go world. As a more concrete example, where users previously needed to do this:

// main.go
package main

import "net/http"

func init() {
  http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
    rw.Write([]byte("Hello world!"))
  })
}

You can now do:

// main.go
package main

import (
  "net/http"

)

func main() {
  http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) {
    rw.Write([]byte("Hello world!"))
  })

  appengine.Main() // required!
}

With this change, we're now enforcing a few more restrictions on where main packages can be and what they are required to do (they were previously just ignored). Here are the new rules if you want to use a custom main:

*  Similar to Flex, main() must call "appengine.Main()" (https://godoc.org/google.golang.org/appengine#Main) in order to ensure that the server is started and the environment is initialized correctly. The docs for this function will be updated shortly to include this information.
*  All imports must be from the GOPATH. Application relative imports will not be picked up.
*  The file containing the main package with the main function must be at the root of the application directory.

The last one has been causing failures for some users because they have application binaries (such as in a "commands" directory under the application root) that are being picked up by go-app-builder. To avoid receiving "package main must be the top-level package" error my recommendation is to add the "nobuild_files" directive to your app.yaml and explicitly exclude the binaries. This should fix the immediate issue and also avoid recompiling them when running dev_appserver. :)

For example, if your binaries are live under a directory named "commands":

// app.yaml
runtime: go
api_version: go1
nobuild_files: commands/.* # THIS IS THE IMPORTANT PART. :)
handlers:
  - url: /.*
    script: _goapp

...


This will all also be mentioned in the RELEASE NOTES for the upcoming SDK 1.9.46 that we're currently packaging up (including the Sierra fix!!!) and are aiming to release next week.

If anyone encounters any other issues or a case that can't be resolved with nobuild_files please respond here and let me know.

Thanks,
Adam




pet...@bueller.us

unread,
Oct 25, 2016, 4:19:47 PM10/25/16
to google-appengine-go
Hi Adam,

This feature uses a buggy version of go vet. Specifically, I've recently encountered #9171 "composite literal uses unkeyed fields" for slice types. This bug prevents some completely correct apps from deploying, even though they worked before this server-side change. No amount of fiddling with app.yaml fixes this: we had to rewrite our apps and all of their dependencies to work around this. Where will breaking (or potentially breaking) server-side changes be announced in the future before they are implemented? Also, why was this change not rolled back once it was understood that it broke some deployments?

Thanks,
Peter
Message has been deleted

Todd Moore

unread,
Nov 15, 2016, 5:47:16 PM11/15/16
to google-appengine-go
I'm attempting to fix this issue but I can't get it resolved.  I've been able to previous run and deploy my project so I attempted to follow your instructions but still get the error.
I never had a package main or a main function (only init) and I guess this is required now?  Can someone give me a link to sample code that will actually run?
The guestbook code hasn't been converted as you describe above:  https://github.com/GoogleCloudPlatform/appengine-guestbook-go/tree/part4-usingdatastore

On Thursday, October 20, 2016 at 9:36:36 PM UTC-4, Adam Tanner wrote:

Todd Moore

unread,
Nov 16, 2016, 10:01:39 AM11/16/16
to google-appengine-go
I fixed my issue because I had some go libraries that used package main.  Once I deleted those files that defined themselves as 'package main' my project compiled again.

de...@pathoz.com

unread,
Sep 16, 2017, 9:24:38 PM9/16/17
to google-appengine-go
I've been struggling constantly with this stupid double-import problem

2017/09/16 20:11:06 go-app-builder: Failed parsing input: app file account_settings.go conflicts with same file imported from GOPATH

Can you please tell me how to fix it??
Thx,
D
Reply all
Reply to author
Forward
0 new messages