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:
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).
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.
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).
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):
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.
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.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Observation
While verifying token scope for #33 (2026-07-03), calling
create_project_from_templatewith notemplate_name(i.e. the server-configured default template) returned: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:template-go-agent).partial_failurefor a template that legitimately has none.Repro
Next step
--template/TEMPLATE_*server config for the gitea-mcp deployment).Refs
internal/tools/create_project_from_template.go(thelen(FilesSubstituted)==0branch).Resolved. Decision: keep
template-go-webas 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-webwas seeded from the realhostexecutorproject and never parameterized.go.modwasmodule gitea.d-ma.be/mathias/hostexecutorandhostexecutorappeared 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__(renamedcmd/hostexecutor→cmd/__PROJECT_NAME__), matching the tool's substitution. Also drops the stalegitea.d-ma.behost — the placeholder resolves togit.d-ma.be/<owner>/<name>.Verified: a default
create_project_from_template(notemplate_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):
hyperguild new-project. That's the tracked async-generate issue, not this one.template-go-web's.gitea/workflows/cd.ymlnow can't build the placeholdered source, so the template repo's own CI will go red (it also shouldn't self-deployhostexecutor). Filing a follow-up to gate/remove CI-on-the-template-repo.Closing #44.