API Error 400 "Text Content Blocks Must Be Non-Empty": Causes and 5 Fixes berarti permintaan Anthropic Messages API berisi setidaknya satu blok teks yang nilai text-nya kosong. Permintaan mungkin terlihat valid di tingkat pesan, tetapi penyedia menolaknya sebelum generasi karena blok konten teks harus berisi setidaknya satu karakter.
Perbaikan cepatnya sederhana: hapus blok teks kosong, trim input pengguna yang hanya berisi whitespace sebelum membangun request, dan jangan pernah mengirim blok placeholder seperti {"type":"text","text":""}. Bagian yang lebih sulit adalah menemukan di mana blok-blok itu diperkenalkan. Dalam aplikasi produksi, blok tersebut sering berasal dari draft UI chat, chunk retrieval kosong, pembersih markdown, variabel template, buffer transcript streaming, atau adapter multimodal yang membangun array content sebelum mengetahui apakah teks sudah ada.
Gunakan panduan ini untuk men-debug error, memperbaiki request builder, dan menambahkan guard preflight agar 400 yang sama tidak muncul lagi.
Jawaban Cepat: API Error 400 "Text Content Blocks Must Be Non-Empty"
Anthropic menerima content pesan sebagai string biasa atau array blok konten bertipe. Dalam bentuk array, sebuah blok teks terlihat seperti ini:
{
"type": "text",
"text": "Ringkas tiket dukungan ini."
}
Ini gagal karena field text kosong:
{
"type": "text",
"text": ""
}
Ini juga dapat gagal dalam praktik jika aplikasi Anda menormalkan nilai yang hanya berisi whitespace menjadi string kosong:
{
"type": "text",
"text": " "
}
Aturan paling aman adalah:
- Trim nilai teks sebelum membangun request Anthropic.
- Buang blok teks yang teks yang sudah di-trim kosong.
- Jika sebuah pesan tidak memiliki blok konten tersisa, jangan kirim pesan itu.
- Log bentuk payload yang sudah disanitasi tanpa mencatat teks prompt pribadi.
- Tambahkan unit test untuk string kosong, whitespace, null, dan hasil retrieval kosong.
Itulah perbaikan praktis untuk API Error 400 "Text Content Blocks Must Be Non-Empty": Causes and 5 Fixes.
Mengapa Error Ini Terjadi
Messages API milik Anthropic menggunakan turn percakapan terstruktur. Setiap pesan input memiliki role dan content. Nilai content dapat berupa satu string, atau dapat berupa array blok seperti blok teks dan gambar. Referensi resmi Messages API menjelaskan content string sebagai singkatan untuk satu blok teks dan mencantumkan text pada blok teks dengan minLength: 1.
Referensi error Anthropic mengklasifikasikan HTTP 400 sebagai invalid_request_error: masalah pada format atau konten request. Jadi ini bukan rate limit, kegagalan autentikasi, gangguan provider, atau masalah kualitas model. Ini adalah masalah validasi request.
Untuk tim produk AI, pelajaran operasionalnya penting: mencoba ulang request yang sama tidak akan membantu. Anda perlu memperbaiki payload sebelum mencoba lagi.
Lima Penyebab Umum
1. Input Chat Kosong Tiba di API
Jalur yang paling umum adalah composer chat yang mengizinkan pengguna mengirim draft kosong atau draft yang menjadi kosong setelah di-trim.
Permintaan buruk:
{
"model": "claude-sonnet-5",
"max_tokens": 512,
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "" }
]
}
]
}
Perbaiki sebelum pemanggilan API:
const input = userInput.trim();
if (!input) {
throw new Error("Teks pesan diperlukan sebelum memanggil Anthropic.");
}
const messages = [
{
role: "user",
content: input
}
];
Gunakan pesan validasi tingkat produk di UI. Jangan biarkan backend menemukan prompt kosong dari 400 milik provider.
2. Retrieval Menambahkan Chunk Kosong
Pipeline RAG sering memetakan dokumen yang diambil ke dalam bagian-bagian prompt. Jika hasil retrieval memiliki cuplikan kosong, body HTML yang dihapus, atau field OCR yang gagal, adapter dapat membuat blok teks kosong.
Adapter buruk:
const content = retrievedDocs.map((doc) => ({
type: "text",
text: doc.cleanedText
}));
Adapter yang lebih aman:
const content = retrievedDocs
.map((doc) => (doc.cleanedText ?? "").trim())
.filter(Boolean)
.map((text) => ({ type: "text", text }));
Jika model membutuhkan konteks sumber, simpan juga jumlah chunk yang dibuang. Jika setiap chunk yang diambil kosong, hentikan dan kembalikan error retrieval alih-alih mengirim prompt kosong.
3. Variabel Template Dirender Menjadi Kosong
Template prompt adalah penyebab umum lainnya dari API Error 400 "Text Content Blocks Must Be Non-Empty": Causes and 5 Fixes. Sebuah template bisa terlihat terisi di kode tetapi merender bagian kosong saat runtime:
const prompt = `
Pesan pelanggan:
${customerMessage}
`;
Jika customerMessage adalah undefined, null, atau kosong setelah dibersihkan, prompt final bisa jadi tidak berguna atau kosong.
Gunakan field wajib yang eksplisit:
function requiredText(name: string, value: unknown): string {
const text = String(value ?? "").trim();
if (!text) {
throw new Error(`Field prompt wajib hilang: ${name}`);
}
return text;
}
const prompt = `Pesan pelanggan:\n${requiredText("customerMessage", customerMessage)}`;
Ini mengubah error provider yang samar menjadi error aplikasi lokal dengan nama field yang hilang.
4. Builder Multimodal Menambahkan Blok Teks Placeholder
Tim yang membangun alur gambar-plus-teks terkadang menginisialisasi array content dengan blok teks placeholder dan mengisinya nanti. Jika teks bersifat opsional dan tidak ada teks yang masuk, placeholder tetap kosong.
Pola buruk:
[
{ "type": "text", "text": "" },
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "..."
}
}
]
Pola yang lebih aman:
const content: Array<Record<string, unknown>> = [];
const instruction = optionalInstruction.trim();
if (instruction) {
content.push({ type: "text", text: instruction });
}
content.push({
type: "image",
source: imageSource
});
Bangun blok hanya ketika konten yang соответствing memang ada. Jangan gunakan blok teks kosong sebagai pemisah.
5. Kompaksi Riwayat Pesan Menyisakan Giliran Kosong
Asisten yang berjalan lama sering mengompaksi atau meringkas giliran sebelumnya. Jika langkah kompaksi menghapus isi pesan tetapi meninggalkan gilirannya dalam riwayat, permintaan Anda dapat berisi pesan asisten atau pengguna yang kosong.
Contoh kegagalan:
{
"role": "assistant",
"content": [
{ "type": "text", "text": "" }
]
}
Gunakan sanitiser riwayat sebelum setiap panggilan:
type TextBlock = { type: "text"; text: string };
type Message = { role: "user" | "assistant"; content: string | TextBlock[] };
function sanitizeMessages(messages: Message[]): Message[] {
return messages.flatMap((message) => {
if (typeof message.content === "string") {
const text = message.content.trim();
return text ? [{ ...message, content: text }] : [];
}
const content = message.content
.map((block) => ({ ...block, text: block.text.trim() }))
.filter((block) => block.type !== "text" || block.text.length > 0);
return content.length ? [{ ...message, content }] : [];
});
}
Kemudian pastikan bahwa setidaknya ada satu pesan yang tersisa sebelum memanggil API.
Validator Pra-Pemeriksaan yang Dapat Disalin
Gunakan validator pra-pemeriksaan permintaan di dekat batas jaringan akhir. Ini menangkap blok kosong bahkan jika UI, template, RAG, atau modul memori di hulu melewatkannya.
type ContentBlock =
| { type: "text"; text?: unknown }
| { type: string; [key: string]: unknown };
type AnthropicMessage = {
role: "user" | "assistant";
content: string | ContentBlock[];
};
export function validateAnthropicMessages(messages: AnthropicMessage[]) {
const cleaned = messages.flatMap((message, messageIndex) => {
if (typeof message.content === "string") {
const text = message.content.trim();
return text ? [{ ...message, content: text }] : [];
}
const content = message.content.flatMap((block, blockIndex) => {
if (block.type !== "text") return [block];
const text = String(block.text ?? "").trim();
if (!text) {
console.warn("Dropped empty Anthropic text block", {
messageIndex,
blockIndex
});
return [];
}
return [{ ...block, text }];
});
return content.length ? [{ ...message, content }] : [];
});
if (!cleaned.length) {
throw new Error("Anthropic request has no non-empty message content.");
}
return cleaned;
}
Ini sengaja dibuat konservatif. Ini menghapus blok teks kosong, mempertahankan blok non-teks, menghapus pesan kosong, dan menolak memanggil model jika tidak ada konten pesan yang dapat digunakan yang tersisa.
Versi Python
Jika backend Anda menggunakan Python, gunakan pemeriksaan batas yang sama:
def sanitize_anthropic_messages(messages):
cleaned_messages = []
for message_index, message in enumerate(messages):
content = message.get("content")
if isinstance(content, str):
text = content.strip()
if text:
cleaned_messages.append({**message, "content": text})
continue
if isinstance(content, list):
cleaned_blocks = []
for block_index, block in enumerate(content):
if block.get("type") != "text":
cleaned_blocks.append(block)
continue
text = str(block.get("text") or "").strip()
if text:
cleaned_blocks.append({**block, "text": text})
else:
print(
"Menghapus blok teks Anthropic yang kosong",
{"message_index": message_index, "block_index": block_index},
)
if cleaned_blocks:
cleaned_messages.append({**message, "content": cleaned_blocks})
if not cleaned_messages:
raise ValueError("Permintaan Anthropic tidak memiliki konten pesan yang non-kosong.")
return cleaned_messages
Jaga agar metadata log tetap struktural. Jangan log prompt pengguna mentah, dokumen pelanggan, atau teks retrieval privat kecuali kebijakan privasi dan alur kerja debugging Anda secara eksplisit mengizinkannya.
Checklist Debugging
Ketika API Error 400 "Text Content Blocks Must Be Non-Empty": Penyebab dan 5 Solusi muncul di production, lakukan debugging dengan urutan berikut:
| Pemeriksaan | Apa yang diperiksa | Perbaikan |
|---|---|---|
| Input UI | Draf pengguna kosong atau hanya berisi whitespace | Blokir pengiriman sampai teks yang sudah di-trim ada |
| Template prompt | Variabel wajib dirender sebagai kosong | Validasi field yang wajib berdasarkan nama |
| Chunk RAG | cleanedText kosong, hasil OCR, atau body markdown kosong |
Filter chunk dan gagal jika semua konteks kosong |
| Permintaan multimodal | Blok teks placeholder sebelum blok gambar/file | Hanya kirim blok teks ketika teks ada |
| Komplikasi riwayat | Pembicaraan user atau assistant kosong setelah ringkasan | Sanitasi daftar pesan akhir |
| Batas jaringan | Payload akhir masih berisi text: "" |
Tambahkan validator preflight dan unit test |
Payload jaringan akhir adalah sumber kebenaran. Jika log Anda tidak menunjukkan blok teks kosong, pastikan SDK tidak mengonversi null, undefined, atau array kosong menjadi blok teks selama serialisasi.
Unit Test yang Perlu Ditambahkan
Minimal, tambahkan test untuk kasus-kasus berikut:
const cases = [
{ name: "string kosong polos", content: "" },
{ name: "string whitespace polos", content: " " },
{ name: "blok teks kosong", content: [{ type: "text", text: "" }] },
{ name: "field text hilang", content: [{ type: "text" }] },
{ name: "field text null", content: [{ type: "text", text: null }] },
{ name: "blok teks valid", content: [{ type: "text", text: "Hello" }] }
];
Perilaku yang Anda harapkan harus eksplisit:
- Pesan hanya teks yang kosong dihapus atau ditolak secara lokal.
- Teks valid tetap ada dengan spasi di awal dan akhir dihapus.
- Blok konten non-teks dipertahankan.
- Permintaan tanpa konten yang dapat digunakan akan error sebelum memanggil Anthropic.
- Error yang dilempar mengidentifikasi batas aplikasi Anda, bukan hanya respons penyedia.
Di Mana Flatkey Berperan
Jika tim Anda merutekan trafik Claude melalui Flatkey, pertahankan disiplin payload Anthropic yang sama. Panduan SDK Anthropic dari Flatkey menunjukkan base_url="https://router.flatkey.ai" untuk jalur SDK Anthropic, sementara API yang kompatibel dengan OpenAI menggunakan https://router.flatkey.ai/v1 untuk permintaan gaya chat-completions. Gunakan rute yang sesuai dengan client dan bentuk endpoint Anda.
Untuk error ini, Flatkey paling berguna sebagai lapisan operasional di sekitar perbaikannya:
- Pertahankan satu tempat untuk memverifikasi apakah permintaan mencapai gateway.
- Bandingkan status permintaan dan bukti penggunaan setelah retry yang berhasil.
- Pertahankan smoke test kecil yang terpisah dari prompt lengkap pengguna.
- Hindari mencampur permintaan format Anthropic dan permintaan yang kompatibel dengan OpenAI dalam adapter yang sama.
Jika Anda sedang memilih rute untuk workload Claude, baca Claude API Proxy vs Multi-Model Router. Jika Anda menstandarkan cara engineer melakukan panggilan aman pertama mereka, simpan Flatkey API quickstart di dekat Anda. Untuk pengecekan produksi yang lebih luas, padukan ini dengan AI routing API metrics dan AI model catalog guide.
Yang Tidak Boleh Dilakukan
Jangan menyelesaikan API Error 400 "Text Content Blocks Must Be Non-Empty": Penyebab dan 5 Solusi dengan retry membabi buta. Penyedia memberi tahu Anda bahwa permintaan tersebut tidak valid.
Hindari pola anti berikut:
| Pola anti | Mengapa gagal |
|---|---|
| Men-retry payload yang sama | Error validasi yang deterministik akan terus gagal |
Mengganti teks kosong dengan "." |
Ini menyembunyikan kehilangan data dari upstream dan dapat mengubah perilaku model |
| Mengirim turn assistant yang kosong | Ini mencemari riwayat dan dapat merusak kelanjutan respons |
| Mencatat prompt lengkap untuk debug | Ini dapat mengekspos data pelanggan atau rahasia |
| Hanya memperbaiki UI | Job backend, RAG, webhook, dan loop agen masih dapat membuat blok kosong |
Perbaikan yang tahan lama adalah memvalidasi konten di batas produsen dan di batas API akhir.
FAQ
Apakah ini gangguan di Anthropic?
Tidak. invalid_request_error 400 untuk blok teks kosong adalah masalah validasi permintaan. Periksa payload yang dikirim aplikasi Anda.
Bisakah saya mengirim string biasa вместо array blok teks?
Ya. Messages API Anthropic memungkinkan content pesan berupa string, dan dokumentasinya menjelaskan itu sebagai singkatan untuk satu blok teks. Gunakan string saat Anda hanya membutuhkan teks sederhana. Gunakan array saat Anda membutuhkan beberapa blok atau input multimodal.
Haruskah spasi dianggap sebagai tidak kosong?
Anggap teks yang hanya berisi spasi sebagai kosong dalam validator Anda sendiri. Bahkan jika suatu penyedia menerimanya, itu bukan konten prompt yang berguna dan biasanya menunjukkan bug pada UI, template, atau retrieval.
Apakah pesan yang hanya berisi gambar bisa berfungsi?
Permintaan multimodal tidak memerlukan placeholder teks kosong. Jika Anda menyertakan blok gambar, buat blok gambar secara langsung dan tambahkan blok teks hanya saat Anda memiliki teks instruksi yang benar-benar nyata.
Apa yang harus saya log?
Log jumlah pesan, jenis blok konten, indeks blok, model, endpoint, route, status code, dan request ID jika tersedia. Hindari logging teks prompt lengkap kecuali aturan privasi tim Anda mengizinkannya.
Referensi Resmi
- Referensi Anthropic Messages API: https://platform.claude.com/docs/en/api/messages
- Referensi error API Anthropic: https://platform.claude.com/docs/en/api/errors
- Panduan Anthropic Messages API: https://platform.claude.com/docs/en/build-with-claude/working-with-messages
- Panduan SDK Anthropic Flatkey: https://docs.flatkey.ai/guides/anthropic-sdk.md
- Ikhtisar API Flatkey: https://docs.flatkey.ai/api-reference/overview.md



