Skip to content

Bug: prompt_async returns 400 - part IDs must start with "prt" #19

Description

@drewsephski

Bug

POST /session/{id}/prompt_async returns 400 because the backend validates that part IDs must start with "prt", but generatePartId() in packages/core/src/api/prompt.ts produces IDs like part-1742244612345-0.

Root Cause

Two issues:

1. Part ID prefix mismatch

// packages/core/src/api/prompt.ts:25-27
let partIdCounter = 0
function generatePartId(): string {
    return `part-${Date.now()}-${partIdCounter++}`  // ❌ backend expects "prt" prefix
}

The backend validates part IDs with a regex requiring the prt prefix. The convertToApiParts function in utils/prompt-api.ts also generates IDs using crypto.randomUUID() which don't match either.

2. SDK errors silently swallowed

The generated @hey-api/openapi-ts SDK returns { error: { status, statusText, body } } objects for non-2xx responses instead of throwing. Effect.tryPromise in packages/core/src/atoms/sessions.ts only catches thrown errors, so HTTP 400 responses resolve as success — the UI shows "prompt sent successfully" but the backend rejected it.

// packages/core/src/atoms/sessions.ts:162-174
yield* Effect.tryPromise({
    try: async (_signal) => {
        const result = await client.session.promptAsync({...})
        // result.error is never checked — 400 looks like success
        return result
    },
    catch: (error) => new Error(`Failed to send prompt: ${...}`),
})

Impact

  • All prompt sends silently fail with 400
  • User sees no error toast ("prompt sent successfully" log)
  • New messages never appear in the chat

Fix

  1. Change prefix from part- to prt- in generatePartId()
  2. Check result.error after SDK call and throw if present

Logs

POST /api/opencode/4056/session/ses_xxx/prompt_async 400
Backend error: Expected a string starting with "prt", got "test-1" at ["parts"][0]["id"]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions