<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Model Gateway on Margrop Blog</title>
		<link>https://blog.margrop.net/en/tag/model-gateway/</link>
		<description>Recent content in Model Gateway on Margrop Blog</description>
		<generator>Hugo</generator>
		<language>en-US</language>
		
		
		
		
			<lastBuildDate>Fri, 29 May 2026 15:30:00 +0800</lastBuildDate>
		
			<atom:link href="https://blog.margrop.net/en/tag/model-gateway/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Claude Code Upgrade Broke Every Model? Before You Rotate Keys, Check the Compatibility Gateway</title>
				<link>https://blog.margrop.net/en/post/claude-code-invalid-message-role-system/</link>
				<pubDate>Fri, 29 May 2026 15:30:00 +0800</pubDate>
				<guid>https://blog.margrop.net/en/post/claude-code-invalid-message-role-system/</guid>
				<description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;The short version&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;After a Claude Code upgrade, every model call failed with the same error: &lt;code&gt;API Error: 400 invalid params, chat content has invalid message role: system (2013)&lt;/code&gt;. At first glance this looks like a bad API key, a dead model, an exhausted account, a broken proxy, or a provider-wide outage. The root cause was different: a newer Claude Code request shape crossed an Anthropic-compatible model gateway that had not caught up with the client-side protocol behavior. The gateway, or a downstream chat validation layer behind it, rejected a &lt;code&gt;system&lt;/code&gt; role in a place where it did not expect one.&lt;/p&gt;&#xA;&lt;p&gt;The practical fix was not to randomly reinstall things. I reproduced the failure with the smallest possible prompt, tested adjacent Claude Code versions, and found the last known good version. &lt;code&gt;2.1.150&lt;/code&gt; returned &lt;code&gt;OK&lt;/code&gt;; &lt;code&gt;2.1.154&lt;/code&gt; and &lt;code&gt;2.1.156&lt;/code&gt; reproduced the 400. Pinning the global Claude Code installation back to &lt;code&gt;2.1.150&lt;/code&gt; restored the existing provider path.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This post is a troubleshooting write-up for a local Claude Code environment. The fix itself was small, but the incident is useful because it shows a pattern that is becoming common in AI agent tooling: the CLI, environment settings, model gateway, API compatibility layer, and actual model backend are often separate moving pieces. When one layer changes its request structure, the terminal may only show a vague 400.&lt;/p&gt;&#xA;&lt;p&gt;All private details have been removed. This article does not include real internal addresses, usernames, tokens, private provider names, local absolute paths, or private service domains. Configuration examples use placeholders such as &lt;code&gt;&amp;lt;PLACEHOLDER&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;MODEL_GATEWAY&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;MODEL_NAME&amp;gt;&lt;/code&gt;. The goal is to document a reusable debugging method, not to expose a specific environment.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
