Found while fixing #4012 (PR #4084), where the regression test needed a temp project booted through the CLI. Unrelated to that fix, so filing rather than expanding scope (AGENTS.md Prime Directive #10).
Symptom
os serve objectstack.config.ts fails during boot whenever dist/objectstack.json is absent beside the config:
Loading objectstack.config.ts...
[StandaloneStack] artifact read FAILED: path='<cwd>/dist/objectstack.json' error=ENOENT: no such file or directory
✗ Service 'manifest' is async - use await
Exit code 1. The thrower is packages/core/src/kernel.ts:106 — getService finds the service in the plugin loader as an unresolved Promise and refuses it.
Repro — it is not about the fixture being minimal
The clean control is examples/app-todo, which boots fine normally:
cd examples/app-todo
mv dist/objectstack.json /tmp/ # the ONLY change
os serve objectstack.config.ts --port 44318
# ✗ Service 'manifest' is async - use await → exit 1
mv /tmp/objectstack.json dist/ # restore
os serve objectstack.config.ts --port 44318
# ✓ Server is ready
So a known-good app fails purely because its compiled artifact is missing. Any freshly-authored project — os init and then os serve before a first os compile — hits the same wall.
The earlier warning
With #4084's boot-diagnostics fix applied, the preceding boot WARN is now visible and points at the same root:
WARN [AppPlugin] failed to seed persisted package state {"error":"Service 'objectql' is async - use await"}
AppPlugin reaches for objectql (and later manifest) while those services are still async factories mid-resolution. With the artifact present something else resolves them first and the race never opens. Worth noting that this warning was itself invisible before #4084 — the failure gave no clue as to why.
Why it matters
Config-boot is a documented, first-class path — serve prints Loading objectstack.config.ts... and its own not-found hint offers objectstack build as one option among others, not a prerequisite. The error message names neither the missing artifact nor the fix, so it reads as an internal fault rather than "run os compile first".
What "fixed" looks like
Either AppPlugin awaits the services it depends on (so no artifact is required and config-boot works as documented), or — if a prebuilt artifact really is mandatory — serve should detect the absent artifact up front and refuse with a message that says so and names os compile.
Workaround
Run os compile before os serve. (That is what #4084's e2e fixture does.)
Found while fixing #4012 (PR #4084), where the regression test needed a temp project booted through the CLI. Unrelated to that fix, so filing rather than expanding scope (AGENTS.md Prime Directive #10).
Symptom
os serve objectstack.config.tsfails during boot wheneverdist/objectstack.jsonis absent beside the config:Exit code 1. The thrower is
packages/core/src/kernel.ts:106—getServicefinds the service in the plugin loader as an unresolvedPromiseand refuses it.Repro — it is not about the fixture being minimal
The clean control is
examples/app-todo, which boots fine normally:So a known-good app fails purely because its compiled artifact is missing. Any freshly-authored project —
os initand thenos servebefore a firstos compile— hits the same wall.The earlier warning
With #4084's boot-diagnostics fix applied, the preceding boot WARN is now visible and points at the same root:
AppPluginreaches forobjectql(and latermanifest) while those services are still async factories mid-resolution. With the artifact present something else resolves them first and the race never opens. Worth noting that this warning was itself invisible before #4084 — the failure gave no clue as to why.Why it matters
Config-boot is a documented, first-class path —
serveprintsLoading objectstack.config.ts...and its own not-found hint offersobjectstack buildas one option among others, not a prerequisite. The error message names neither the missing artifact nor the fix, so it reads as an internal fault rather than "runos compilefirst".What "fixed" looks like
Either
AppPluginawaits the services it depends on (so no artifact is required and config-boot works as documented), or — if a prebuilt artifact really is mandatory —serveshould detect the absent artifact up front and refuse with a message that says so and namesos compile.Workaround
Run
os compilebeforeos serve. (That is what #4084's e2e fixture does.)