Buffalo 启动卡在 “Starting application…” 是因阻塞操作无超时或日志,最常见为数据库未就绪或 migration 卡住;需检查 database.yml 连通性、注释 DB 初始化、验证 migration 是否 hang 住。

buffalo dev 启动卡在 “Starting application…” 不报错
这是最常见的假死现象,本质是 Buffalo 在等待某个阻塞操作完成,但没设超时或没输出日志。最常见原因是数据库连接未就绪或 migration 脚本卡住。
检查点:
- 确认
database.yml中的host、port、user、password能被当前环境解析和访问(比如 Docker 容器内连宿主机 PostgreSQL 用host.docker.internal,而非localhost) - 临时注释掉
app.Use(popmw.Transaction)和所有pop.Connect相关初始化代码,看是否能跳过 DB 阶段启动 - 运行
buffalo db migrate status,观察是否 hang 住——若 hang,说明 pop 连接池已建立但 migration SQL 执行卡在某条语句(如加锁表、缺失索引导致慢查询)
panic: runtime error: invalid memory address or nil pointer dereference
典型出现在自定义中间件或 action handler 中调用了未初始化的依赖,比如 c.DB() 返回 nil 时直接链式调用 .All(),或 c.Param("id") 后没判空就转成 int。
实操建议:
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
- 在
actions/app.go的App()函数末尾加一行log.Printf("DB connection: %v", app.DB()),确认app.DB()是否为 nil - 所有
c.Param()、c.QueryParam()、c.Request().Header.Get()的结果,必须先判断是否为空字符串再做类型转换 - 如果用了
buffalo.PopTransaction(),确保它只在已注册 DB 的 context 下使用;否则改用显式tx, err := app.DB().Transaction()并检查err
buffalo build 失败,提示 “failed to load template” 或 “plush: parse error”
即使你用 --api 创建项目,Buffalo 仍默认加载 templates/ 下的 plush 模板。只要目录存在且有语法错误的 .html 文件,buffalo build 就会失败。
关键动作:
- 删掉整个
templates/目录(纯 API 服务不需要任何模板渲染) - 检查
go.mod是否还残留github.com/gobuffalo/plush或github.com/gobuffalo/packr/v2,有则手动go mod edit -droprequire删除 - 搜索项目中所有
c.Render()调用,替换为c.JSON()或c.Error();若保留c.Render(),必须确保第一个参数是r.HTML(...)且对应文件真实存在、无语法错误
启动后 502 / 404 / 空白响应,但日志无报错
这类问题往往出在路由注册顺序或中间件拦截上。Buffalo 的 app.Use() 是链式执行,一旦某个中间件没调用 c.Next(),后续 handler 就永远不会执行。
排查步骤:
- 在
app.go的App()函数里,在所有app.Use(...)前加一行app.Use(func(next buffalo.Handler) buffalo.Handler { return func(c buffalo.Context) error { log.Printf("→ %s %s", c.Request().Method, c.Request().URL.Path); defer log.Printf("← %s %s", c.Request().Method, c.Request().URL.Path); return next(c) } }),确认请求是否进入中间件链 - 检查是否有中间件(比如自定义鉴权)在特定条件下直接
return c.Error(401, ...)却没写响应体,导致前端收空包 - 确认
routes/app.go中的路由是否匹配路径:Buffalo 默认不自动加前缀,app.GET("/users", ...)对应的是GET /users,不是/api/v1/users;若前端请求带版本前缀,后端没配路由就会 404

















