slopus/happy · error · Error
request-upload returned an invalid response
Error message
request-upload returned an invalid response
What it means
Thrown by requestAttachmentUpload when the server's response to the request-upload call fails structural validation: upload is missing, ref/uploadUrl are not strings, or method is present but not PUT or POST. The client treats this as a contract violation of the upload API rather than a transport error.
Source
Thrown at packages/happy-cli/src/api/apiSession.ts:429
private async requestAttachmentUpload(filename: string, size: number): Promise<AttachmentUploadResult> {
const response = await axios.post<AttachmentUploadResult>(
`${configuration.serverUrl}/v1/sessions/${encodeURIComponent(this.sessionId)}/attachments/request-upload`,
{ filename, size },
{
headers: this.authHeaders(),
timeout: 30000,
},
);
const upload = response.data;
if (
!upload
|| typeof upload.ref !== 'string'
|| typeof upload.uploadUrl !== 'string'
|| (upload.method !== undefined && upload.method !== 'PUT' && upload.method !== 'POST')
) {
throw new Error('request-upload returned an invalid response');
}
return {
...upload,
method: upload.method ?? 'PUT',
};
}
private async uploadEncryptedAttachmentBlob(upload: AttachmentUploadResult, encrypted: Uint8Array): Promise<void> {
if (upload.method === 'POST') {
const { body, boundary } = buildMultipartUploadBody(upload.formFields, encrypted);
await axios.post(upload.uploadUrl, body, {
headers: {
'Content-Type': `multipart/form-data; boundary=${boundary}`,
},
timeout: 60000,
maxBodyLength: 10 * 1024 * 1024,
});View on GitHub (pinned to b824cd0a46)
Solutions
- Check server logs and the raw response for the real cause (auth failure, 4xx/5xx body)
- Verify CLI and server versions are compatible — update the CLI or server
- Confirm the attachment upload endpoint is enabled/reachable and retry
Defensive patterns
Strategy: validation
Validate before calling
const res = await requestUpload(attachmentId);
const ok = res?.data?.ref && typeof res.data.uploadUrl === 'string'
&& ['PUT', 'POST', undefined].includes(res.data.method);
if (!ok) throw new Error('unexpected request-upload response'); Type guard
function isValidUploadResponse(u: any): u is { ref: string; uploadUrl: string; method?: 'PUT' | 'POST' } {
return !!u && typeof u.ref === 'string' && typeof u.uploadUrl === 'string'
&& (u.method === undefined || u.method === 'PUT' || u.method === 'POST');
} Try / catch
try {
await upload(attachmentPath);
} catch (e) {
if (e.message.includes('invalid response')) {
// log raw server response; likely version skew or auth issue
} throw e;
} Prevention
- Pin matching CLI/server versions
- Log raw request-upload responses when debugging
- Check auth status before attachment operations
When it happens
Trigger: Server returns an error body, empty data, or a malformed payload for request-upload; an API version skew changes the response shape (renamed fields, missing uploadUrl, unsupported method value).
Common situations: Pointing the CLI at an older/proxy server that doesn't implement request-upload; authenticated but unauthorized requests returning error JSON; server bug or partial outage.
Related errors
AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31).
Data as JSON: /api/errors/60b09f90ed2a87f1.
Report an issue: GitHub.