create_project_from_template: server-default template yields "no placeholders substituted" #44

Closed
opened 2026-07-03 19:26:33 +00:00 by mathias · 1 comment
Owner

Observation

While verifying token scope for #33 (2026-07-03), calling create_project_from_template with no template_name (i.e. the server-configured default template) returned:

partial_failure: "no placeholders substituted in scope-check-tmpl@main — verify the scaffold is not left templated"
files_substituted: null

The repo generated fine (no scope/API error) — but the default template contains no __PROJECT_NAME__ / __MODULE_PATH__ placeholders, so the whole-tree substitution walk finds nothing and the loud-check (correctly, by its own logic) flags it.

Why it matters

The default path is the zero-config happy path a claude.ai caller hits first. Right now that path always returns a partial_failure, which reads as "something broke" even though repo creation succeeded. Two possibilities:

  1. The server-configured default template is wrong / stale — it points at a repo that doesn't use the placeholder convention. Fix = point the default at a real placeholdered template (e.g. template-go-agent).
  2. The default template is intentionally static (no placeholders) — then the loud-check is a false alarm for it, and "nothing substituted" shouldn't be surfaced as partial_failure for a template that legitimately has none.

Repro

create_project_from_template(owner=mathias, name=<throwaway>, private=true)   # no template_name

Next step

  • Confirm what the deployed default template is (the --template/TEMPLATE_* server config for the gitea-mcp deployment).
  • Decide (1) vs (2). If (1): fix the default. If (2): distinguish "template has no placeholders by design" from "substitution failed" so the happy path returns clean success.

Refs

  • Surfaced during #33 verification.
  • Loud-check logic: internal/tools/create_project_from_template.go (the len(FilesSubstituted)==0 branch).
## Observation While verifying token scope for #33 (2026-07-03), calling `create_project_from_template` with **no `template_name`** (i.e. the server-configured default template) returned: ``` partial_failure: "no placeholders substituted in scope-check-tmpl@main — verify the scaffold is not left templated" files_substituted: null ``` The repo generated fine (no scope/API error) — but the default template contains no `__PROJECT_NAME__` / `__MODULE_PATH__` placeholders, so the whole-tree substitution walk finds nothing and the loud-check (correctly, by its own logic) flags it. ## Why it matters The default path is the zero-config happy path a claude.ai caller hits first. Right now that path always returns a `partial_failure`, which reads as "something broke" even though repo creation succeeded. Two possibilities: 1. **The server-configured default template is wrong / stale** — it points at a repo that doesn't use the placeholder convention. Fix = point the default at a real placeholdered template (e.g. `template-go-agent`). 2. **The default template is intentionally static** (no placeholders) — then the loud-check is a false alarm for it, and "nothing substituted" shouldn't be surfaced as `partial_failure` for a template that legitimately has none. ## Repro ``` create_project_from_template(owner=mathias, name=<throwaway>, private=true) # no template_name ``` ## Next step - Confirm what the deployed default template is (the `--template`/`TEMPLATE_*` server config for the gitea-mcp deployment). - Decide (1) vs (2). If (1): fix the default. If (2): distinguish "template has no placeholders by design" from "substitution failed" so the happy path returns clean success. ## Refs - Surfaced during #33 verification. - Loud-check logic: `internal/tools/create_project_from_template.go` (the `len(FilesSubstituted)==0` branch).
Author
Owner

Resolved. Decision: keep template-go-web as the server default, fix it (it matches the default HTMX+Templ stack).

Root cause (not a loud-check false alarm — the loud-check was correct): template-go-web was seeded from the real hostexecutor project and never parameterized. go.mod was module gitea.d-ma.be/mathias/hostexecutor and hostexecutor appeared throughout (cmd dir, Dockerfile, Taskfile, CI, all the context docs). So the tool found zero placeholders and returned "no placeholders substituted".

Fix (template-go-web 8a22a28): replaced the full module path → __MODULE_PATH__ and the bare name → __PROJECT_NAME__ (renamed cmd/hostexecutorcmd/__PROJECT_NAME__), matching the tool's substitution. Also drops the stale gitea.d-ma.be host — the placeholder resolves to git.d-ma.be/<owner>/<name>.

Verified: a default create_project_from_template (no template_name) now attempts substitution — the result changed from "no placeholders substituted" to an infra#179 branch-race message, and it was mid-write on .aider.conventions.md (a substituted file) when the branch wasn't yet writable. So placeholders are found and substituted; the loud false-negative is gone.

No gitea-mcp code change — default stays template-go-web; the loud-check is correct as-is.

Residuals (separate, pre-existing):

  1. infra#179 — gitea's async template-generate is slow on this instance, so the 5s substitution budget still races and defers to hyperguild new-project. That's the tracked async-generate issue, not this one.
  2. template self-CItemplate-go-web's .gitea/workflows/cd.yml now can't build the placeholdered source, so the template repo's own CI will go red (it also shouldn't self-deploy hostexecutor). Filing a follow-up to gate/remove CI-on-the-template-repo.

Closing #44.

Resolved. Decision: **keep `template-go-web` as the server default, fix it** (it matches the default HTMX+Templ stack). **Root cause** (not a loud-check false alarm — the loud-check was correct): `template-go-web` was seeded from the real `hostexecutor` project and never parameterized. `go.mod` was `module gitea.d-ma.be/mathias/hostexecutor` and `hostexecutor` appeared throughout (cmd dir, Dockerfile, Taskfile, CI, all the context docs). So the tool found zero placeholders and returned "no placeholders substituted". **Fix** (template-go-web `8a22a28`): replaced the full module path → `__MODULE_PATH__` and the bare name → `__PROJECT_NAME__` (renamed `cmd/hostexecutor` → `cmd/__PROJECT_NAME__`), matching the tool's substitution. Also drops the stale `gitea.d-ma.be` host — the placeholder resolves to `git.d-ma.be/<owner>/<name>`. **Verified:** a default `create_project_from_template` (no `template_name`) now **attempts substitution** — the result changed from `"no placeholders substituted"` to an infra#179 branch-race message, and it was mid-write on `.aider.conventions.md` (a substituted file) when the branch wasn't yet writable. So placeholders are found and substituted; the loud false-negative is gone. **No gitea-mcp code change** — default stays `template-go-web`; the loud-check is correct as-is. **Residuals (separate, pre-existing):** 1. **infra#179** — gitea's async template-generate is slow on this instance, so the 5s substitution budget still races and defers to `hyperguild new-project`. That's the tracked async-generate issue, not this one. 2. **template self-CI** — `template-go-web`'s `.gitea/workflows/cd.yml` now can't build the placeholdered source, so the template repo's own CI will go red (it also shouldn't self-deploy `hostexecutor`). Filing a follow-up to gate/remove CI-on-the-template-repo. Closing #44.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/gitea-mcp#44