Skip to content

Commit d353a6b

Browse files
authored
fix(worktree): accept missing create payload (anomalyco#27582)
1 parent d25cc42 commit d353a6b

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

packages/opencode/src/server/routes/instance/httpapi/groups/experimental.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,9 @@ export const ExperimentalApi = HttpApi.make("experimental")
166166
}),
167167
),
168168
HttpApiEndpoint.post("worktreeCreate", ExperimentalPaths.worktree, {
169+
disableCodecs: true,
169170
query: WorkspaceRoutingQuery,
170-
payload: Schema.optional(Worktree.CreateInput),
171+
payload: Schema.UndefinedOr(Worktree.CreateInput),
171172
success: described(Worktree.Info, "Worktree created"),
172173
error: WorktreeApiError,
173174
}).annotateMerge(

packages/opencode/test/server/worktree-endpoint-repro.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ function createWorktreeScoped(input: {
129129
input.timeoutLabel,
130130
input.timeoutMs,
131131
)
132+
if (response.status !== 200) {
133+
const message = yield* Effect.promise(() => response.text())
134+
throw new Error(`${input.timeoutLabel} failed: ${response.status} ${message}`)
135+
}
132136
expect(response.status).toBe(200)
133137
const body = yield* json<CreatedWorktree>(response)
134138
return { directory: body.directory, body, ready: waitReady(body.directory) } satisfies ScopedWorktree
@@ -186,6 +190,46 @@ describe("worktree endpoint reproduction", () => {
186190
{ git: true },
187191
)
188192

193+
worktreeTest(
194+
"direct HttpApi worktree create accepts missing body",
195+
() =>
196+
Effect.gen(function* () {
197+
const test = yield* TestInstance
198+
const server = yield* serverScoped()
199+
200+
const response = yield* createWorktreeScoped({
201+
server,
202+
directory: test.directory,
203+
path: `${ExperimentalPaths.worktree}?directory=${encodeURIComponent(test.directory)}`,
204+
init: { method: "POST", headers: { "content-type": "application/json" } },
205+
timeoutLabel: "direct worktree create without body",
206+
})
207+
208+
expect(response).toMatchObject({ directory: expect.any(String) })
209+
}),
210+
{ git: true },
211+
)
212+
213+
worktreeTest(
214+
"direct HttpApi worktree create accepts missing content type and body",
215+
() =>
216+
Effect.gen(function* () {
217+
const test = yield* TestInstance
218+
const server = yield* serverScoped()
219+
220+
const response = yield* createWorktreeScoped({
221+
server,
222+
directory: test.directory,
223+
path: `${ExperimentalPaths.worktree}?directory=${encodeURIComponent(test.directory)}`,
224+
init: { method: "POST" },
225+
timeoutLabel: "direct worktree create without content type or body",
226+
})
227+
228+
expect(response).toMatchObject({ directory: expect.any(String) })
229+
}),
230+
{ git: true },
231+
)
232+
189233
worktreeTest(
190234
"workspace worktree create does not hang",
191235
() =>

0 commit comments

Comments
 (0)