Found while evaluating 0.24.0-rc.3 in an adopter project.
Summary
meta gen run from a sub-project now walks up to the nearest ancestor .metaobjects/config.json, re-roots the project there, and then demands metaobjects.config.ts at that ancestor — ignoring the metaobjects.config.ts sitting in the directory the command was actually run from.
Any repo whose root is not the TS project — a Maven- or pip-rooted monorepo with one or more JS apps underneath — cannot run meta gen at all.
This is a regression against 0.23.1, verified against the same working tree.
Observed
Layout (Maven-rooted monorepo):
<repo-root>/
pom.xml
.metaobjects/config.json # committed; declares 4 `sources` (added for the cross-port sources feature)
<app>/
metaobjects.config.ts # the real TS codegen config
metaobjects/ # this app's metadata source dir
package.json # independent install root, own bun.lock
From <app>/:
$ meta gen
meta: metaobjects.config.ts not found at <repo-root>/metaobjects.config.ts. Run 'meta init' to scaffold one.
$ echo $?
2
Note the path in the error: the CLI was invoked from <app>/, which has a metaobjects.config.ts, but it is looking at <repo-root>/.
Control — this worked on 0.23.1
Same tree, same command, only the CLI version differs:
| CLI |
result |
0.23.1 |
376 written, exit 0 |
0.24.0-rc.3 |
error above, exit 2 |
Two further probes isolate the cause to the ancestor config:
- Move
<repo-root>/.metaobjects/config.json aside → rc.3 succeeds, 322 written, 54 unchanged (376 total, matching 0.23.1).
- Restore it and add
<app>/.metaobjects/config.json → rc.3 succeeds, 376 total.
So the upward walk stops at the first .metaobjects/config.json it finds, and whichever directory that is becomes the project root for metaobjects.config.ts resolution.
Why the obvious workaround doesn't reach CI
Giving each sub-project its own .metaobjects/config.json fixes it locally. But .metaobjects/ is gitignored in these sub-projects — that ignore rule came from the scaffolder itself, since the directory otherwise holds only generated agent-context files. So the workaround file is untracked and absent on a fresh clone.
The practical result is that CI breaks: a typical frontend job runs bun install --frozen-lockfile then bun run gen (wired as pretest/prebuild), and gen now hard-fails on the runner while passing on a developer machine that happens to have the untracked file.
Suggested fix
Resolve metaobjects.config.ts from the invocation directory (or nearest ancestor that has one), independently of where .metaobjects/config.json is discovered. The two files answer different questions — "what are the metadata sources" vs "how does this package generate TS" — and only the first is reasonably repo-global.
Failing that, .metaobjects/config.json needs a way to say "I am sources-only, do not treat me as the TS project root", and meta init --config-only should emit that form.
Workaround for adopters today
Add a .metaobjects/config.json beside each sub-project's metaobjects.config.ts:
{ "schema_version": 1, "sources": [ { "path": "metaobjects" } ] }
and un-ignore it so CI sees it. Note the sources in that file replace the defaults, so it must name the app's own metadata dir — pointing it elsewhere silently shrinks the generated set (one wrong path took a 376-file run down to 6).
Found while evaluating
0.24.0-rc.3in an adopter project.Summary
meta genrun from a sub-project now walks up to the nearest ancestor.metaobjects/config.json, re-roots the project there, and then demandsmetaobjects.config.tsat that ancestor — ignoring themetaobjects.config.tssitting in the directory the command was actually run from.Any repo whose root is not the TS project — a Maven- or pip-rooted monorepo with one or more JS apps underneath — cannot run
meta genat all.This is a regression against
0.23.1, verified against the same working tree.Observed
Layout (Maven-rooted monorepo):
From
<app>/:Note the path in the error: the CLI was invoked from
<app>/, which has ametaobjects.config.ts, but it is looking at<repo-root>/.Control — this worked on 0.23.1
Same tree, same command, only the CLI version differs:
0.23.1376 written, exit 00.24.0-rc.3Two further probes isolate the cause to the ancestor config:
<repo-root>/.metaobjects/config.jsonaside → rc.3 succeeds,322 written, 54 unchanged(376 total, matching 0.23.1).<app>/.metaobjects/config.json→ rc.3 succeeds, 376 total.So the upward walk stops at the first
.metaobjects/config.jsonit finds, and whichever directory that is becomes the project root formetaobjects.config.tsresolution.Why the obvious workaround doesn't reach CI
Giving each sub-project its own
.metaobjects/config.jsonfixes it locally. But.metaobjects/is gitignored in these sub-projects — that ignore rule came from the scaffolder itself, since the directory otherwise holds only generated agent-context files. So the workaround file is untracked and absent on a fresh clone.The practical result is that CI breaks: a typical frontend job runs
bun install --frozen-lockfilethenbun run gen(wired aspretest/prebuild), andgennow hard-fails on the runner while passing on a developer machine that happens to have the untracked file.Suggested fix
Resolve
metaobjects.config.tsfrom the invocation directory (or nearest ancestor that has one), independently of where.metaobjects/config.jsonis discovered. The two files answer different questions — "what are the metadata sources" vs "how does this package generate TS" — and only the first is reasonably repo-global.Failing that,
.metaobjects/config.jsonneeds a way to say "I am sources-only, do not treat me as the TS project root", andmeta init --config-onlyshould emit that form.Workaround for adopters today
Add a
.metaobjects/config.jsonbeside each sub-project'smetaobjects.config.ts:{ "schema_version": 1, "sources": [ { "path": "metaobjects" } ] }and un-ignore it so CI sees it. Note the
sourcesin that file replace the defaults, so it must name the app's own metadata dir — pointing it elsewhere silently shrinks the generated set (one wrong path took a 376-file run down to 6).