Skip to content

os doctor 载入 objectstack.config.ts 时不带 .env* overlay —— 配置文件自己读 process.env 时,doctor 报「Could not load config」而 os serve 同目录正常启动 #5397

Description

@baozhoutao

发现于 #5387(doctor 对齐 serve 的 .env* 读取顺序)实施过程中的顺带核验;本单只记录,不在该 PR 里改 —— 原因写在下面。

事实

#5387 之后,doctor 会按 os serve 的顺序读 .env*,但读到的值只在需要它的那一次读取周围临时生效(withDotenvOverlay),刻意不合并进整轮运行的 process.env。今天套上 overlay 的只有 env 派生检查(posture)那一处;loadConfig() 没有套。

两条命令的顺序因此仍然不同:

  • serve:dotenvFlow.config()(packages/cli/src/commands/serve.ts:520)→ 之后才 bundleRequire 载入用户的 objectstack.config.ts。配置文件顶层读到的 process.env .env* 的值。
  • doctor:readDotenvFiles()(不写 process.env)→ loadConfig()(packages/cli/src/commands/doctor.ts 的 config 分析块)。配置文件顶层读到的 process.env 不含 .env* 的值。

后果

配置文件在顶层读环境变量是常见写法(数据源 URL、开关)。当变量只写在 .env 里时:

  1. 值不同 —— 依赖该值的结构(条件声明的 object / datasource)在 doctor 与 serve 眼里不是同一份,doctor 的 config 检查判定的是一份服务器不会运行的配置;

  2. 更响的一种 —— 配置在缺值时抛错(throw new Error('OS_DATABASE_URL is required') 之类),doctor 会落进 config 分析那个很宽的 try,打印

    ⚠ Could not load config for analysis (config checks skipped)
    

    记一个 warning、exit 0,而 os serve 在同一个目录正常启动。这句话正是 os doctor 对非法 OS_TENANCY_POSTURE 退出码 0 并报告「环境功能正常」—— 抛错被 config 分析的宽 catch 吞成一句「Could not load config」 #5382 判定为「归因错误」的那一句:配置本身没问题,问题是 doctor 没把 .env 交给它。

为什么没有顺手改

loadConfig() 套上 overlay 会改变既有 config 检查(circular deps / unused objects / orphan views / dashboard integrity / spec 版本)的输入,可能新增或消除 warning —— 属于诊断输出的另一处契约变化,超出 #5387 派发时被限定的判定面(该单的口径明确要求:若改变既有检查的判定超出预期就停下报告)。

需要决定的是同一个问题的另一半:doctor 的 config 分析应当在哪一份环境下进行 —— serve 的那份(overlay 覆盖 loadConfig(),与运行时一致,但既有检查的判定面会变),还是当前这份(只覆盖显式声明的 env 输入,判定面不变,但 config 那条路径与 serve 仍不一致)。

现状

零件已经就位,不需要新机制:readDotenvFiles() / withDotenvOverlay() 就在同一个文件里(#5387 引入,packages/cli/src/commands/doctor.ts),把 loadConfig() 的调用包进去即可。packages/cli 下没有任何测试钉 doctor 的 config 载入与 .env 的关系。

Depends-on: #5387(其 PR 引入的两个零件是本单的前置)。与 #4801、cloud#1020 同属「诊断面与运行时不一致」家族。


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions